0

I am using Service Fabric stateful services to store state about users in the system. My partitioning strategy is to use the normalized international string format phone number to address a named service instance, and the hash of the phone number to resolve a partition of that service. EX: fabric:/myapp/users/1/718 (where the international phone number is +1718xxxxxxx) This allows me to geo-locate services based on their country (and further in the US/Canada markets by area code).

My question is sort of theoretical, but also practical in nature. Who owns the logic for service resolution? A simple approach is to just require anyone taking a dependency on this service to know how its partitioned, but that feels like a leaky abstraction to me. Furthermore, I would like to assign an Id to the user which is divorced from the concept of a phone number.

  1. My original approach was to make the Id a byte[] which included the service name, partition id, and local id of the user. I dropped this idea since the size of the ID was very large, and would add up over time. (this is problematic because all keys in a Reliable Dictionary need to fit into memory and I'd rather not kill a ton of memory on ids) Also, it still carries with it the baggage of everyone using the id knowing how to interpret the id and use it accordingly.
  2. My next idea was to provide a client library to anyone consuming the service. This also has the drawback of a binary dependency of a consuming service. If i want to change the strategy in the future, I have to jump through a bunch of hoops to handle failures to correctly resolve the entity.
  3. The last alternative i can think of is to have a stateless proxy in front of stateful service which handles the resolution for all services. This is the most appealing from a design perspective but also involves managing, building another service just for resolution. Not opposed to it, but it is an additional consideration. If i go this route, should I tread this service as a separate service fabric application, or is it advisable to keep everything as one application.

I also, am open to entertaining the idea that partitioning users this way is a bad idea. However, using the phone is advisable for a number of reasons.

Justin Blakley
  • 458
  • 4
  • 16

1 Answers1

1

I'd recommend keeping any knowledge about partitioning away from your service consumers, if possible. This way you can change the service internals without changing anything at the consumer-side.

That leads to option 3, combined with the built-in reverse proxy service. In that extra service, you can look up the authenticated user and use its location to determine the service partition.

If you make it a new application, it can become the entrypoint (/proxy) for multiple bounded contexts

LoekD
  • 11,402
  • 17
  • 27
  • Can you expand on the "Combined with the built-in reverse proxy service" idea? Currently I'm using GRPC as my communication protocol for services inside the external boundary of the cluster. – Justin Blakley Aug 08 '17 at 15:38
  • On second thought, forget about the RP bit, it would just add overhead. sorry – LoekD Aug 11 '17 at 07:26