Skip to main content

Architecture

Flux is built to be horizontally scalable and not make any database calls as part of a customer request since we don't want the database to become a bottleneck during peak loads.

This is achieved by heavily caching all data needed to calculate discounts for customer requests. All caching implementations in Flux uses memory by default. Which is a great default, but if you have more specific requirements you can implement your own cache services to use eg Redis as a central cache.

When changes occur change events are broadcasted using IFluxEventBroker which has three implementations, one for single server use, one that uses the database as event store, and one using RabbitMQ. You can add your own implementation using a message broker of choice if you want to.

When the change event is picked up by the different caches they will refresh themselves in the background. This is important as some cache invalidation implementations will drop the cache when a change occur and rely on the next call to detect an empty cache and fetch it from the database. Flux will instead keep using the stale cache until the background refresh is finished to avoid adding any direct dependency on the database for customer traffic.

Tags

Tags are a central concept of Flux and it's used on most of the core entities. Tags go hand in hand with Conditions which are set on discounts, pricelists, etc to match entities.

Tags are much like any attribute-value implementation, but they are named tags rather than attributes because Flux is not meant to store the full data for eg products. If you decide to store products in Flux the product tags you create should only be the ones you need for discount targeting. Another reason for them being tags instead of attributes is that they are supposed to be shaped for matching. Oftentimes you want your product attributes to be the raw data. Eg availability might be calculated from a number of product attributes and in that case you want a single tag for availability in Flux rather than discount creators having to build complex conditions to target the correct attributes.

Catalog sync is optional

When we designed Flux we didn't want to create another hard dependency of syncing the entire catalog to another system. If the sync fails or is delayed in some way we didn't want that to affect the correctness of discounts. So when you ask Flux to calculate discounts from a cart you don't only send in identifiers (eg product key) but you send all of the product tags as part of the calculation call.

Which means that it doesn't matter if the catalog sync has a delay or is down at the moment, Flux is basing it's condition calculations on the tags passed in rather than the tags from the catalog sync.

With that said it is possible to omit tags in calculation calls and let Flux fetch them from the product data stored in Flux. But then you need to have high confidence in the catalog sync.

The catalog sync into Flux is entirely optional optional, but it makes it a lot easier to build and test discounts in the Flux UI if there's products in the system.

Subscriptions

Flux realizes that it's not alone and not the one system that all other systems revolve around. Sending notifications to other systems for current and future discount prices is a core concept of Flux as it enables you to show discounted prices everywhere and not just in your cart. Subscriptions lets you set up Flux to ping your other systems when current and future discount prices change.