Search code examples
f#akka.nethocon

How to specify HashMapping when using Hocon


Given the HOCON below for a consitent-hashing-poolrouter, how do I specify the hashMapping.

    akka {
      actor {
        serializers {
          wire = "Akka.Serialization.WireSerializer, Akka.Serialization.Wire"
        }
        serialization-bindings {
          "System.Object" = wire
        }
        deployment {
          /data-collector {
            router = consistent-hashing-pool
            nr-of-instances = 10
          }
        }
      }
      loggers = ["Akka.Logger.NLog.NLogLogger,Akka.Logger.NLog"]
    }

Given

let config = Configuration.load()
let systemName = config.GetString("app-config.actorsystem", "my-system")
let system = System.create systemName config
let collectorRouter = 
  let hashMapping (msg:obj) =
    match msg with
    | :? Message as msg ->
        match msg with
        | Parse (_, req) -> req.uniqueId |> box
    | _ -> "-" |> box
  ConsistentHashingPool (10, ConsistentHashMapping hashMapping)
let dataCollectorProps = 
  { props (dataCollector settings.collector) with
      Router = Some (collectorRouter :> RouterConfig)} //(FromConfig.Instance.WithFallback collectorRouter)
let test = spawn system "data-collector" <| dataCollectorProps

Router = Some (collectorRouter :> RouterConfig) work

Router = Some (FromConfig.Instance.WithFallback collectorRouter) doesn't

What is the correct way to specify the hashMapping function?

Edit 1 The warning from the console is

Akka.Routing.ConsistentHashingRoutingLogic|Message [Message] must be handled by hashMapping, or implement [IConsistentHashable] or be wrapped in [ConsistentHashableEnvelope]


Solution

  • There are three ways of specifying the hash key. My favourite is to implement IConsistentHashable and return the key (based on some properties of the message) from the ConsistentHashKey property.

    Example excerpt from my Consistent Hashing article (in C#; sorry I don't know F#):

    public class CurrencyPriceChangeMessage : IConsistentHashable
    {
        public string CurrencyPair { get; }
        public decimal Price { get; }
    
        public object ConsistentHashKey
        {
            get
            {
                return this.CurrencyPair;
            }
        }
    

    The hash key will be used to route messages with the same key always to the same routee.