Kevin
Kevin

Reputation: 40

Akka.net Generic Type Messages

I have an actor whose job is to do some update operations to a Mongo database. I send it a message containing a name value pair and it creates or updates a field within a Mongo document.

The value can be an int, double, or bool. How do I best design the message(s) to send to the actor? Performance and scalability are an issue in this application. I see three possible approaches:

  1. Implement a different message for each data type, then use the handler to act appropriately.

  2. Pass the value as an object within a single message, then cast to the proper type and perform the database operation.

  3. Use generic class messages to somehow send a value of type T that is then handled correctly within a single handler. Note, this seems ideal, but I have not figured out how to properly structure these messages.

Ever grateful for some insight on how to best address this.

Upvotes: 1

Views: 715

Answers (2)

Nsubuga Kasozi
Nsubuga Kasozi

Reputation: 21

So I had the exact same challenge with my actor. I am posting this because this is a top-ranked question on google. Receiving a parametrized generic type in the on Recieve method

    public partial class CacheDataStoreActor : UntypedActor 
    {
         private DataStore.IDataStoreConnector _dataStore;

        public CacheDataStoreActor(DataStore.IDataStoreConnector dataStore)
        {
            _dataStore = dataStore;
        }

        public static Props Create(DataStore.IDataStoreConnector dataStore)
        {
           return Props.Create(() => new CacheDataStoreActor(dataStore));
        }

        protected override void OnReceive(object message)
        {
           switch (message)
           {
              case SaveItemCmd request:
                Task.Run(async () => await ProcessSaveItemCmd(request)).PipeTo(Sender);
                break;

              default:
                 //using the default case then passing the generic type 
                 //as a dynamic to the target method
                Task.Run(async () => await ProcessRetrieveItemQuery(message as dynamic)).PipeTo(Sender);
                break;
           }
     }

And then the method itself would accept the parameterized generic type as usual(Something like this)

    private async Task<T> ProcessRetrieveItemQuery<T>(RetrieveItemQuery<T> request)
    {
        return await _dataStore.RetrieveItem<T>(request.Key, request.QueryFilter);
    }

Upvotes: 0

Kevin
Kevin

Reputation: 40

After further thought and some quick testing, I have decided to use a single message containing one variable for each type....

public class UpdateMessage(string name, bool valueBool, double valueDbl, int valueInt)

This prevents boxing issues and allows me to use a single message and handler. Feedback appreciated.

Upvotes: 0

Related Questions