Code Monkey home page Code Monkey logo

Comments (5)

tdeekens avatar tdeekens commented on August 15, 2024

👋 Hi,

thanks for reaching out.

The combine-adapters module is not documented yet as I wasn't sure how stable it would be. It came out of an internal need at our work and I hence implemented it. It turns out to have worked great for over five months. So documentation in general could follow.

To your challenge, I have to check if using two adapter instances of the same flag provider works. It is something I never thought would be needed. It also depends on the underlying SDK. Moreover, combine-adapters would work but state management is tricky as is uses adapter ids to isolate flag state and track it.

How would you expect things to work if both adapters have to same flag but with a different value for instance?

from flopflip.

don-hover avatar don-hover commented on August 15, 2024

Hi Tobias,

Thank you for replying to my request.

This request is specific to a) how our Saas product works with customers at multiple organizations/accounts, and b) how Split,io works. This is the scenario:

First, we sell our product to customers at different organizations. So you can think of a customer data model like this:

{ 
  customers: [
    {
      id: 1,
      org: 1
    }, {
      id: 2,
      org: 1
    }, {
      id: 3,
      org: 2
    }, {
      id: 4,
      org: 2
    }, {
      id: 5,
      org: 3
    }
  ]
}

So, we have some flags that we would turn on/off at the org level (like for org: 1), and some that we use at the user level.

Second, Split.io has the concept of "traffic type" - this allows a client SDK to be instantiated that is "connected" to a traffic type. In our case, we have two traffic types - org and user. So, when we set up feature flag targeting rules, they are based on either org or user. And - this is important - a feature flag definition exists only once, for only one traffic type - either org or user, but not for both. So, essentially there is a map of flags, and each flag is of traffic type org or user, but there are separate client SDK instance required to access the two different traffic types. There is no problem about the same flag existing in both client instances.

That last part is what made me think of combining the adapters. In our current internal flag implementation wrapping Split.io, we create two client SDK instances, and then evaluate a flag against each instance. This works, but it meant that we had to essentially re-create the entire Split React components ourselves to work with the multiple client instances. With flipflop, it looks like we could do something similar by creating a custom adapter that contains two client instances. But I was wondering if the CombinedAdapter might also work for this.

If the CombinedAdapter won't work for this, could you provide me with any details on creating a custom adapter? I saw that the docs say an adapter requires only a configure and reconfigure method - but I don't understand how that would support custom flag state evaluation logic, or even how the flag evaluation would be communicated to the flipflop state through these two functions. If you have any docs or examples for this, that would be very helpful.

Thank you very much!

Don

from flopflip.

tdeekens avatar tdeekens commented on August 15, 2024

Thanks for the detailed explanation. I think I can follow along.

Given that a flag can not exist in both traffic types simplifies things a bit.

Each adapter in flopflip instanciates an underlying SDK only once. So one can not have two split.io or launchdarkly SDK instances per adapter running. That doesn't mean it isn't possible but just not something build/supported at the moment. So one could extend the split.io adapter in a to be discussed manner to create two SDK instances. This would then simplify your code as you discribed.

Alternatively one could use combine-adapters. However, even a combineAdapters of two split.io adapters still only yields one split.io SDK instance as an adapter is a singleton. Combine adapter is more of a use case to use two different adapters. For instance we use lanchdarkly and graphql. One for short-lived flags, the other for long running configuration. Leading me to a third thought.

Feature flags should be short-lived and are ideally not long-lived configuration. I don't want to suggest a solution but mention this. One can also build a custom adapter or the http adapter hitting a custom end point (for instance graphql) to expose flags which are long running configuration.

Back to the original issue. I think in order to have two split.io SDK instances the internals of the split.io adapter has to be adjusted to support it. Best to check out the code. Also in regards to building a custom adapter I would argue code is the best documentation here. Some adapters are really small and in general they don't need much besides two methods and an event emitter.

Hope this helps.

from flopflip.

don-hover avatar don-hover commented on August 15, 2024

Hi Tobias,

Thanks for the response on this.

I did take a look at the code for the Split.io adapter here:
https://github.com/tdeekens/flopflip/blob/master/packages/splitio-adapter/src/adapter/adapter.ts

Parts of this code are similar to the code we have internally for our Split flag handling. When you say "in order to have two split.io SDK instances the internals of the split.io adapter has to be adjusted to support it", that would be fine - it seems to me that we could create our own custom adapter, something like MultiClientSplitioAdapter.

The part that I'm not clear on in the code is how the flag state is communicated from the adapter(s) to the flipflop library state. The only public methods in the adapter seem to be configure, reconfigure, and updateFlags. Is updating the main library flag state from the adapter flag state done via the events in the adapter, and by the adapter calling onFlagsStateChange()? If so, I don't see where that function is defined and provided to the adapter class instance.

In any case, I think what I'm trying to ask is if this approach sounds valid to you:

  1. Create a new adapter class MultiClientSplitioAdapter.
  2. In this class, change the adapter code to accept an array of configuration objects, that each have the sdk.authorizationKey, sdk.options, and sdk. treatmentAttributes properties.
  3. In the adapter initialization, iterate through the array of config objects to create one SDK client instance for each config object; manage these clients in a this.#adapterState.clients array, instead of a single client object.
  4. When listening for flag updates, listen on all clients; send a flag update event when any flag on any client changes.

Could you let me know if a) you think this can be implemented as described in a custom adapter, and b) if an implementation like this will work with the interface of the main flipflop library code?

Thanks a lot,
Don

from flopflip.

tdeekens avatar tdeekens commented on August 15, 2024

Hi,

yes building your own adapter is an option if you don't want to extend the current adapter supporting multiple instance of the SDK. Maybe it's a good strategy to build your own adapter and see where it ends up. If it's general enough I'd obviously be happy to receive contributions.

The flag state and adapter state (configuration state) is communicated through callbacks which are passed to the adapter through the configure method. The end up on the instance here. These must then be used to pass information outward the adapter. Think of it as an onChange on a controlled React input. Here one of them is invoked to get the flag state out of the adapter.

This state (both flag and adapter) is then used in either the context or redux and exposed through it. That's why the library has two variants (redux and broadcast). Essentially all state emitted by the adapter is held by either redux or a React context (in the broadcast package) which then allows us to useFeatureToggle as if things never lived outside of React.

Hope this helps.

from flopflip.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.