#//#shared
#####################################
# Akka Remote Reference Config File #
#####################################

# This is the reference config file that contains all the default settings.
# Make your edits/overrides in your application.conf.

# comments about akka.actor settings left out where they are already in akka-
# actor.jar, because otherwise they would be repeated in config rendering.
#
# For the configuration of the new remoting implementation (Artery) please look
# at the bottom section of this file as it is listed separately.

akka {

  actor {

    serializers {
      akka-containers = "akka.remote.serialization.MessageContainerSerializer"
      akka-misc = "akka.remote.serialization.MiscMessageSerializer"
      artery = "akka.remote.serialization.ArteryMessageSerializer"
      proto = "akka.remote.serialization.ProtobufSerializer"
      daemon-create = "akka.remote.serialization.DaemonMsgCreateSerializer"
      akka-system-msg = "akka.remote.serialization.SystemMessageSerializer"
    }

    serialization-bindings {
      "akka.actor.ActorSelectionMessage" = akka-containers

      "akka.remote.DaemonMsgCreate" = daemon-create

      "akka.remote.artery.ArteryMessage" = artery

      # Since akka.protobuf.Message does not extend Serializable but
      # GeneratedMessage does, need to use the more specific one here in order
      # to avoid ambiguity.
      # This is only loaded if akka-protobuf is on the classpath
      # It should not be used and users should migrate to using the protobuf classes
      # directly
      # Remove in 2.7
      "akka.protobuf.GeneratedMessage" = proto

      "akka.protobufv3.internal.GeneratedMessageV3" = proto

      # Since com.google.protobuf.Message does not extend Serializable but
      # GeneratedMessage does, need to use the more specific one here in order
      # to avoid ambiguity.
      # This com.google.protobuf serialization binding is only used if the class can be loaded,
      # i.e. com.google.protobuf dependency has been added in the application project.
      "com.google.protobuf.GeneratedMessage" = proto
      "com.google.protobuf.GeneratedMessageV3" = proto

      "akka.actor.Identify" = akka-misc
      "akka.actor.ActorIdentity" = akka-misc
      "scala.Some" = akka-misc
      "scala.None$" = akka-misc
      "java.util.Optional" = akka-misc
      "akka.actor.Status$Success" = akka-misc
      "akka.actor.Status$Failure" = akka-misc
      "akka.actor.ActorRef" = akka-misc
      "akka.actor.PoisonPill$" = akka-misc
      "akka.actor.Kill$" = akka-misc
      "akka.remote.RemoteWatcher$Heartbeat$" = akka-misc
      "akka.remote.RemoteWatcher$HeartbeatRsp" = akka-misc
      "akka.Done" = akka-misc
      "akka.NotUsed" = akka-misc
      "akka.actor.Address" = akka-misc
      "akka.remote.UniqueAddress" = akka-misc

      "akka.actor.ActorInitializationException" = akka-misc
      "akka.actor.IllegalActorStateException" = akka-misc
      "akka.actor.ActorKilledException" = akka-misc
      "akka.actor.InvalidActorNameException" = akka-misc
      "akka.actor.InvalidMessageException" = akka-misc
      "java.util.concurrent.TimeoutException" = akka-misc
      "akka.remote.serialization.ThrowableNotSerializableException" = akka-misc

      "akka.actor.LocalScope$" = akka-misc
      "akka.remote.RemoteScope" = akka-misc

      "com.typesafe.config.impl.SimpleConfig" = akka-misc
      "com.typesafe.config.Config" = akka-misc

      "akka.routing.FromConfig" = akka-misc
      "akka.routing.DefaultResizer" = akka-misc
      "akka.routing.BalancingPool" = akka-misc
      "akka.routing.BroadcastGroup" = akka-misc
      "akka.routing.BroadcastPool" = akka-misc
      "akka.routing.RandomGroup" = akka-misc
      "akka.routing.RandomPool" = akka-misc
      "akka.routing.RoundRobinGroup" = akka-misc
      "akka.routing.RoundRobinPool" = akka-misc
      "akka.routing.ScatterGatherFirstCompletedGroup" = akka-misc
      "akka.routing.ScatterGatherFirstCompletedPool" = akka-misc
      "akka.routing.SmallestMailboxPool" = akka-misc
      "akka.routing.TailChoppingGroup" = akka-misc
      "akka.routing.TailChoppingPool" = akka-misc
      "akka.remote.routing.RemoteRouterConfig" = akka-misc

      "akka.pattern.StatusReply" = akka-misc

      "akka.dispatch.sysmsg.SystemMessage" = akka-system-msg

      # Java Serializer is by default used for exceptions and will by default
      # not be allowed to be serialized, but in certain cases they are replaced
      # by `akka.remote.serialization.ThrowableNotSerializableException` if
      # no specific serializer has been defined:
      # - when wrapped in `akka.actor.Status.Failure` for ask replies
      # - when wrapped in system messages for exceptions from remote deployed child actors
      #
      # It's recommended that you implement custom serializer for exceptions that are
      # sent remotely, You can add binding to akka-misc (MiscMessageSerializer) for the
      # exceptions that have a constructor with single message String or constructor with
      # message String as first parameter and cause Throwable as second parameter. Note that it's not
      # safe to add this binding for general exceptions such as IllegalArgumentException
      # because it may have a subclass without required constructor.
      "java.lang.Throwable" = java
    }

    serialization-identifiers {
      "akka.remote.serialization.ProtobufSerializer" = 2
      "akka.remote.serialization.DaemonMsgCreateSerializer" = 3
      "akka.remote.serialization.MessageContainerSerializer" = 6
      "akka.remote.serialization.MiscMessageSerializer" = 16
      "akka.remote.serialization.ArteryMessageSerializer" = 17

      "akka.remote.serialization.SystemMessageSerializer" = 22

      # deprecated in 2.6.0, moved to akka-actor
      "akka.remote.serialization.LongSerializer" = 18
      # deprecated in 2.6.0, moved to akka-actor
      "akka.remote.serialization.IntSerializer" = 19
      # deprecated in 2.6.0, moved to akka-actor
      "akka.remote.serialization.StringSerializer" = 20
      # deprecated in 2.6.0, moved to akka-actor
      "akka.remote.serialization.ByteStringSerializer" = 21
    }

    deployment {

      default {

        # if this is set to a valid remote address, the named actor will be
        # deployed at that node e.g. "akka://sys@host:port"
        remote = ""

        target {

          # A list of hostnames and ports for instantiating the children of a
          # router
          #   The format should be on "akka://sys@host:port", where:
          #    - sys is the remote actor system name
          #    - hostname can be either hostname or IP address the remote actor
          #      should connect to
          #    - port should be the port for the remote server on the other node
          # The number of actor instances to be spawned is still taken from the
          # nr-of-instances setting as for local routers; the instances will be
          # distributed round-robin among the given nodes.
          nodes = []

        }
      }
    }
  }

  remote {
    ### Settings shared by classic remoting and Artery (the new implementation of remoting)

    # Using remoting directly is typically not desirable, so a warning will
    # be shown to make this clear. Set this setting to 'off' to suppress that
    # warning.
    warn-about-direct-use = on


    # If Cluster is not used, remote watch and deployment are disabled.
    # To optionally use them while not using Cluster, set to 'on'.
    use-unsafe-remote-features-outside-cluster = off

    # A warning will be logged on remote watch attempts if Cluster
    # is not in use and 'use-unsafe-remote-features-outside-cluster'
    # is 'off'. Set this to 'off' to suppress these.
    warn-unsafe-watch-outside-cluster = on

    # Settings for the Phi accrual failure detector (http://www.jaist.ac.jp/~defago/files/pdf/IS_RR_2004_010.pdf
    # [Hayashibara et al]) used for remote death watch.
    # The default PhiAccrualFailureDetector will trigger if there are no heartbeats within
    # the duration heartbeat-interval + acceptable-heartbeat-pause + threshold_adjustment,
    # i.e. around 12.5 seconds with default settings.
    watch-failure-detector {

      # FQCN of the failure detector implementation.
      # It must implement akka.remote.FailureDetector and have
      # a public constructor with a com.typesafe.config.Config and
      # akka.actor.EventStream parameter.
      implementation-class = "akka.remote.PhiAccrualFailureDetector"

      # How often keep-alive heartbeat messages should be sent to each connection.
      heartbeat-interval = 1 s

      # Defines the failure detector threshold.
      # A low threshold is prone to generate many wrong suspicions but ensures
      # a quick detection in the event of a real crash. Conversely, a high
      # threshold generates fewer mistakes but needs more time to detect
      # actual crashes.
      threshold = 10.0

      # Number of the samples of inter-heartbeat arrival times to adaptively
      # calculate the failure timeout for connections.
      max-sample-size = 200

      # Minimum standard deviation to use for the normal distribution in
      # AccrualFailureDetector. Too low standard deviation might result in
      # too much sensitivity for sudden, but normal, deviations in heartbeat
      # inter arrival times.
      min-std-deviation = 100 ms

      # Number of potentially lost/delayed heartbeats that will be
      # accepted before considering it to be an anomaly.
      # This margin is important to be able to survive sudden, occasional,
      # pauses in heartbeat arrivals, due to for example garbage collect or
      # network drop.
      acceptable-heartbeat-pause = 10 s


      # How often to check for nodes marked as unreachable by the failure
      # detector
      unreachable-nodes-reaper-interval = 1s

      # After the heartbeat request has been sent the first failure detection
      # will start after this period, even though no heartbeat mesage has
      # been received.
      expected-response-after = 1 s

    }

    # remote deployment configuration section
    deployment {
      # deprecated, use `enable-allow-list`
      enable-whitelist = off

      # If true, will only allow specific classes listed in `allowed-actor-classes` to be instanciated on this
      # system via remote deployment
      enable-allow-list = ${akka.remote.deployment.enable-whitelist}


      # deprecated, use `allowed-actor-classes`
      whitelist = []

      allowed-actor-classes = ${akka.remote.deployment.whitelist}
    }

    ### Default dispatcher for the remoting subsystem
    default-remote-dispatcher {
      type = Dispatcher
      executor = "fork-join-executor"
      fork-join-executor {
        parallelism-min = 2
        parallelism-factor = 0.5
        parallelism-max = 16
      }
      throughput = 10
    }
    #//#shared
  }

}

akka {

  remote.classic {
    #//#classic

    ### Configuration for classic remoting. Classic remoting is deprecated, use artery.


    # If set to a nonempty string remoting will use the given dispatcher for
    # its internal actors otherwise the default dispatcher is used. Please note
    # that since remoting can load arbitrary 3rd party drivers (see
    # "enabled-transport" and "adapters" entries) it is not guaranteed that
    # every module will respect this setting.
    use-dispatcher = "akka.remote.default-remote-dispatcher"

    # Settings for the failure detector to monitor connections.
    # For TCP it is not important to have fast failure detection, since
    # most connection failures are captured by TCP itself.
    # The default DeadlineFailureDetector will trigger if there are no heartbeats within
    # the duration heartbeat-interval + acceptable-heartbeat-pause, i.e. 124 seconds
    # with the default settings.
    transport-failure-detector {

      # FQCN of the failure detector implementation.
      # It must implement akka.remote.FailureDetector and have
      # a public constructor with a com.typesafe.config.Config and
      # akka.actor.EventStream parameter.
      implementation-class = "akka.remote.DeadlineFailureDetector"

      # How often keep-alive heartbeat messages should be sent to each connection.
      heartbeat-interval = 4 s

      # Number of potentially lost/delayed heartbeats that will be
      # accepted before considering it to be an anomaly.
      # A margin to the `heartbeat-interval` is important to be able to survive sudden,
      # occasional, pauses in heartbeat arrivals, due to for example garbage collect or
      # network drop.
      acceptable-heartbeat-pause = 120 s
    }


    # Timeout after which the startup of the remoting subsystem is considered
    # to be failed. Increase this value if your transport drivers (see the
    # enabled-transports section) need longer time to be loaded.
    startup-timeout = 10 s

    # Timout after which the graceful shutdown of the remoting subsystem is
    # considered to be failed. After the timeout the remoting system is
    # forcefully shut down. Increase this value if your transport drivers
    # (see the enabled-transports section) need longer time to stop properly.
    shutdown-timeout = 10 s

    # Before shutting down the drivers, the remoting subsystem attempts to flush
    # all pending writes. This setting controls the maximum time the remoting is
    # willing to wait before moving on to shut down the drivers.
    flush-wait-on-shutdown = 2 s

    # Reuse inbound connections for outbound messages
    use-passive-connections = on

    # Controls the backoff interval after a refused write is reattempted.
    # (Transports may refuse writes if their internal buffer is full)
    backoff-interval = 5 ms

    # Acknowledgment timeout of management commands sent to the transport stack.
    command-ack-timeout = 30 s

    # The timeout for outbound associations to perform the handshake.
    # If the transport is akka.remote.classic.netty.tcp or akka.remote.classic.netty.ssl
    # the configured connection-timeout for the transport will be used instead.
    handshake-timeout = 15 s

    ### Security settings

    # Enable untrusted mode for full security of server managed actors, prevents
    # system messages to be send by clients, e.g. messages like 'Create',
    # 'Suspend', 'Resume', 'Terminate', 'Supervise', 'Link' etc.
    untrusted-mode = off

    # When 'untrusted-mode=on' inbound actor selections are by default discarded.
    # Actors with paths defined in this list are granted permission to receive actor
    # selections messages.
    # E.g. trusted-selection-paths = ["/user/receptionist", "/user/namingService"]
    trusted-selection-paths = []

    ### Logging

    # If this is "on", Akka will log all inbound messages at DEBUG level,
    # if off then they are not logged
    log-received-messages = off

    # If this is "on", Akka will log all outbound messages at DEBUG level,
    # if off then they are not logged
    log-sent-messages = off

    # Sets the log granularity level at which Akka logs remoting events. This setting
    # can take the values OFF, ERROR, WARNING, INFO, DEBUG, or ON. For compatibility
    # reasons the setting "on" will default to "debug" level. Please note that the effective
    # logging level is still determined by the global logging level of the actor system:
    # for example debug level remoting events will be only logged if the system
    # is running with debug level logging.
    # Failures to deserialize received messages also fall under this flag.
    log-remote-lifecycle-events = on

    # Logging of message types with payload size in bytes larger than
    # this value. Maximum detected size per message type is logged once,
    # with an increase threshold of 10%.
    # By default this feature is turned off. Activate it by setting the property to
    # a value in bytes, such as 1000b. Note that for all messages larger than this
    # limit there will be extra performance and scalability cost.
    log-frame-size-exceeding = off

    # Log warning if the number of messages in the backoff buffer in the endpoint
    # writer exceeds this limit. It can be disabled by setting the value to off.
    log-buffer-size-exceeding = 50000

    # After failed to establish an outbound connection, the remoting will mark the
    # address as failed. This configuration option controls how much time should
    # be elapsed before reattempting a new connection. While the address is
    # gated, all messages sent to the address are delivered to dead-letters.
    # Since this setting limits the rate of reconnects setting it to a
    # very short interval (i.e. less than a second) may result in a storm of
    # reconnect attempts.
    retry-gate-closed-for = 5 s

    # After catastrophic communication failures that result in the loss of system
    # messages or after the remote DeathWatch triggers the remote system gets
    # quarantined to prevent inconsistent behavior.
    # This setting controls how long the Quarantine marker will be kept around
    # before being removed to avoid long-term memory leaks.
    # WARNING: DO NOT change this to a small value to re-enable communication with
    # quarantined nodes. Such feature is not supported and any behavior between
    # the affected systems after lifting the quarantine is undefined.
    prune-quarantine-marker-after = 5 d

    # If system messages have been exchanged between two systems (i.e. remote death
    # watch or remote deployment has been used) a remote system will be marked as
    # quarantined after the two system has no active association, and no
    # communication happens during the time configured here.
    # The only purpose of this setting is to avoid storing system message redelivery
    # data (sequence number state, etc.) for an undefined amount of time leading to long
    # term memory leak. Instead, if a system has been gone for this period,
    # or more exactly
    # - there is no association between the two systems (TCP connection, if TCP transport is used)
    # - neither side has been attempting to communicate with the other
    # - there are no pending system messages to deliver
    # for the amount of time configured here, the remote system will be quarantined and all state
    # associated with it will be dropped.
    #
    # Maximum value depends on the scheduler's max limit (default 248 days) and if configured
    # to a longer duration this feature will effectively be disabled. Setting the value to
    # 'off' will also disable the feature. Note that if disabled there is a risk of a long
    # term memory leak.
    quarantine-after-silence = 2 d

    # This setting defines the maximum number of unacknowledged system messages
    # allowed for a remote system. If this limit is reached the remote system is
    # declared to be dead and its UID marked as tainted.
    system-message-buffer-size = 20000

    # This setting defines the maximum idle time after an individual
    # acknowledgement for system messages is sent. System message delivery
    # is guaranteed by explicit acknowledgement messages. These acks are
    # piggybacked on ordinary traffic messages. If no traffic is detected
    # during the time period configured here, the remoting will send out
    # an individual ack.
    system-message-ack-piggyback-timeout = 0.3 s

    # This setting defines the time after internal management signals
    # between actors (used for DeathWatch and supervision) that have not been
    # explicitly acknowledged or negatively acknowledged are resent.
    # Messages that were negatively acknowledged are always immediately
    # resent.
    resend-interval = 2 s

    # Maximum number of unacknowledged system messages that will be resent
    # each 'resend-interval'. If you watch many (> 1000) remote actors you can
    # increase this value to for example 600, but a too large limit (e.g. 10000)
    # may flood the connection and might cause false failure detection to trigger.
    # Test such a configuration by watching all actors at the same time and stop
    # all watched actors at the same time.
    resend-limit = 200

    # WARNING: this setting should not be not changed unless all of its consequences
    # are properly understood which assumes experience with remoting internals
    # or expert advice.
    # This setting defines the time after redelivery attempts of internal management
    # signals are stopped to a remote system that has been not confirmed to be alive by
    # this system before.
    initial-system-message-delivery-timeout = 3 m

    ### Transports and adapters

    # List of the transport drivers that will be loaded by the remoting.
    # A list of fully qualified config paths must be provided where
    # the given configuration path contains a transport-class key
    # pointing to an implementation class of the Transport interface.
    # If multiple transports are provided, the address of the first
    # one will be used as a default address.
    enabled-transports = ["akka.remote.classic.netty.tcp"]

    # Transport drivers can be augmented with adapters by adding their
    # name to the applied-adapters setting in the configuration of a
    # transport. The available adapters should be configured in this
    # section by providing a name, and the fully qualified name of
    # their corresponding implementation. The class given here
    # must implement akka.akka.remote.transport.TransportAdapterProvider
    # and have public constructor without parameters.
    adapters {
      gremlin = "akka.remote.transport.FailureInjectorProvider"
      trttl = "akka.remote.transport.ThrottlerProvider"
    }

    ### Default configuration for the Netty based transport drivers

    netty.tcp {
      # The class given here must implement the akka.remote.transport.Transport
      # interface and offer a public constructor which takes two arguments:
      #  1) akka.actor.ExtendedActorSystem
      #  2) com.typesafe.config.Config
      transport-class = "akka.remote.transport.netty.NettyTransport"

      # Transport drivers can be augmented with adapters by adding their
      # name to the applied-adapters list. The last adapter in the
      # list is the adapter immediately above the driver, while
      # the first one is the top of the stack below the standard
      # Akka protocol
      applied-adapters = []

      # The default remote server port clients should connect to.
      # Default is 2552 (AKKA), use 0 if you want a random available port
      # This port needs to be unique for each actor system on the same machine.
      port = 2552

      # The hostname or ip clients should connect to.
      # InetAddress.getLocalHost.getHostAddress is used if empty
      hostname = ""

      # Use this setting to bind a network interface to a different port
      # than remoting protocol expects messages at. This may be used
      # when running akka nodes in a separated networks (under NATs or docker containers).
      # Use 0 if you want a random available port. Examples:
      #
      # akka.remote.classic.netty.tcp.port = 2552
      # akka.remote.classic.netty.tcp.bind-port = 2553
      # Network interface will be bound to the 2553 port, but remoting protocol will
      # expect messages sent to port 2552.
      #
      # akka.remote.classic.netty.tcp.port = 0
      # akka.remote.classic.netty.tcp.bind-port = 0
      # Network interface will be bound to a random port, and remoting protocol will
      # expect messages sent to the bound port.
      #
      # akka.remote.classic.netty.tcp.port = 2552
      # akka.remote.classic.netty.tcp.bind-port = 0
      # Network interface will be bound to a random port, but remoting protocol will
      # expect messages sent to port 2552.
      #
      # akka.remote.classic.netty.tcp.port = 0
      # akka.remote.classic.netty.tcp.bind-port = 2553
      # Network interface will be bound to the 2553 port, and remoting protocol will
      # expect messages sent to the bound port.
      #
      # akka.remote.classic.netty.tcp.port = 2552
      # akka.remote.classic.netty.tcp.bind-port = ""
      # Network interface will be bound to the 2552 port, and remoting protocol will
      # expect messages sent to the bound port.
      #
      # akka.remote.classic.netty.tcp.port if empty
      bind-port = ""

      # Use this setting to bind a network interface to a different hostname or ip
      # than remoting protocol expects messages at.
      # Use "0.0.0.0" to bind to all interfaces.
      # akka.remote.classic.netty.tcp.hostname if empty
      bind-hostname = ""

      # Enables SSL support on this transport
      enable-ssl = false

      # Sets the connectTimeoutMillis of all outbound connections,
      # i.e. how long a connect may take until it is timed out
      connection-timeout = 15 s

      # If set to "<id.of.dispatcher>" then the specified dispatcher
      # will be used to accept inbound connections, and perform IO. If "" then
      # dedicated threads will be used.
      # Please note that the Netty driver only uses this configuration and does
      # not read the "akka.remote.use-dispatcher" entry. Instead it has to be
      # configured manually to point to the same dispatcher if needed.
      use-dispatcher-for-io = ""

      # Sets the high water mark for the in and outbound sockets,
      # set to 0b for platform default
      write-buffer-high-water-mark = 0b

      # Sets the low water mark for the in and outbound sockets,
      # set to 0b for platform default
      write-buffer-low-water-mark = 0b

      # Sets the send buffer size of the Sockets,
      # set to 0b for platform default
      send-buffer-size = 256000b

      # Sets the receive buffer size of the Sockets,
      # set to 0b for platform default
      receive-buffer-size = 256000b

      # Maximum message size the transport will accept, but at least
      # 32000 bytes.
      # Please note that UDP does not support arbitrary large datagrams,
      # so this setting has to be chosen carefully when using UDP.
      # Both send-buffer-size and receive-buffer-size settings has to
      # be adjusted to be able to buffer messages of maximum size.
      maximum-frame-size = 128000b

      # Sets the size of the connection backlog
      backlog = 4096

      # Enables the TCP_NODELAY flag, i.e. disables Nagle’s algorithm
      tcp-nodelay = on

      # Enables TCP Keepalive, subject to the O/S kernel’s configuration
      tcp-keepalive = on

      # Enables SO_REUSEADDR, which determines when an ActorSystem can open
      # the specified listen port (the meaning differs between *nix and Windows)
      # Valid values are "on", "off" and "off-for-windows"
      # due to the following Windows bug: http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4476378
      # "off-for-windows" of course means that it's "on" for all other platforms
      tcp-reuse-addr = off-for-windows

      # Used to configure the number of I/O worker threads on server sockets
      server-socket-worker-pool {
        # Min number of threads to cap factor-based number to
        pool-size-min = 2

        # The pool size factor is used to determine thread pool size
        # using the following formula: ceil(available processors * factor).
        # Resulting size is then bounded by the pool-size-min and
        # pool-size-max values.
        pool-size-factor = 1.0

        # Max number of threads to cap factor-based number to
        pool-size-max = 2
      }

      # Used to configure the number of I/O worker threads on client sockets
      client-socket-worker-pool {
        # Min number of threads to cap factor-based number to
        pool-size-min = 2

        # The pool size factor is used to determine thread pool size
        # using the following formula: ceil(available processors * factor).
        # Resulting size is then bounded by the pool-size-min and
        # pool-size-max values.
        pool-size-factor = 1.0

        # Max number of threads to cap factor-based number to
        pool-size-max = 2
      }


    }

    netty.ssl = ${akka.remote.classic.netty.tcp}
    netty.ssl = {
      # Enable SSL/TLS encryption.
      # This must be enabled on both the client and server to work.
      enable-ssl = true

      # Factory of SSLEngine.
      # Must implement akka.remote.transport.netty.SSLEngineProvider and have a public
      # constructor with an ActorSystem parameter.
      # The default ConfigSSLEngineProvider is configured by properties in section
      # akka.remote.classic.netty.ssl.security
      #
      # The SSLEngineProvider can also be defined via ActorSystemSetup with
      # SSLEngineProviderSetup  when starting the ActorSystem. That is useful when
      # the SSLEngineProvider implementation requires other external constructor
      # parameters or is created before the ActorSystem is created.
      # If such SSLEngineProviderSetup is defined this config property is not used.
      ssl-engine-provider = akka.remote.transport.netty.ConfigSSLEngineProvider

      security {
        # This is the Java Key Store used by the server connection
        key-store = "keystore"

        # This password is used for decrypting the key store
        key-store-password = "changeme"

        # This password is used for decrypting the key
        key-password = "changeme"

        # This is the Java Key Store used by the client connection
        trust-store = "truststore"

        # This password is used for decrypting the trust store
        trust-store-password = "changeme"

        # Protocol to use for SSL encryption.
        protocol = "TLSv1.2"

        # Example: ["TLS_DHE_RSA_WITH_AES_128_GCM_SHA256", 
        #   "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",
        #   "TLS_DHE_RSA_WITH_AES_256_GCM_SHA384",
        #   "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384"]
        # When doing rolling upgrades, make sure to include both the algorithm used 
        # by old nodes and the preferred algorithm.
        # If you use a JDK 8 prior to 8u161 you need to install
        # the JCE Unlimited Strength Jurisdiction Policy Files to use AES 256.
        # More info here:
        # https://www.oracle.com/java/technologies/javase-jce-all-downloads.html
        enabled-algorithms = ["TLS_DHE_RSA_WITH_AES_256_GCM_SHA384",
          "TLS_RSA_WITH_AES_128_CBC_SHA"]

        # There are two options, and the default SecureRandom is recommended:
        # "" or "SecureRandom" => (default)
        # "SHA1PRNG" => Can be slow because of blocking issues on Linux
        #
        # Setting a value here may require you to supply the appropriate cipher
        # suite (see enabled-algorithms section above)
        random-number-generator = ""

        # Require mutual authentication between TLS peers
        #
        # Without mutual authentication only the peer that actively establishes a connection (TLS client side)
        # checks if the passive side (TLS server side) sends over a trusted certificate. With the flag turned on,
        # the passive side will also request and verify a certificate from the connecting peer.
        #
        # To prevent man-in-the-middle attacks this setting is enabled by default.
        #
        # Note: Nodes that are configured with this setting to 'on' might not be able to receive messages from nodes that
        # run on older versions of akka-remote. This is because in versions of Akka < 2.4.12 the active side of the remoting
        # connection will not send over certificates even if asked.
        #
        # However, starting with Akka 2.4.12, even with this setting "off", the active side (TLS client side)
        # will use the given key-store to send over a certificate if asked. A rolling upgrade from versions of
        # Akka < 2.4.12 can therefore work like this:
        #   - upgrade all nodes to an Akka version >= 2.4.12, in the best case the latest version, but keep this setting at "off"
        #   - then switch this flag to "on" and do again a rolling upgrade of all nodes
        # The first step ensures that all nodes will send over a certificate when asked to. The second
        # step will ensure that all nodes finally enforce the secure checking of client certificates.
        require-mutual-authentication = on
      }
    }

    ### Default configuration for the failure injector transport adapter

    gremlin {
      # Enable debug logging of the failure injector transport adapter
      debug = off
    }

    backoff-remote-dispatcher {
      type = Dispatcher
      executor = "fork-join-executor"
      fork-join-executor {
        # Min number of threads to cap factor-based parallelism number to
        parallelism-min = 2
        parallelism-max = 2
      }
    }
  }
}
#//#classic

#//#artery
akka {

  remote {

    ### Configuration for Artery, the new implementation of remoting
    artery {

      # Disable artery with this flag
      enabled = on

      # Select the underlying transport implementation.
      #
      # Possible values: aeron-udp, tcp, tls-tcp
      # See https://doc.akka.io/docs/akka/current/remoting-artery.html#selecting-a-transport for the tradeoffs
      # for each transport
      transport = tcp

      # Canonical address is the address other clients should connect to.
      # Artery transport will expect messages to this address.
      canonical {

        # The default remote server port clients should connect to.
        # Default is 25520, use 0 if you want a random available port
        # This port needs to be unique for each actor system on the same machine.
        port = 25520

        # Hostname clients should connect to. Can be set to an ip, hostname
        # or one of the following special values:
        #   "<getHostAddress>"   InetAddress.getLocalHost.getHostAddress
        #   "<getHostName>"      InetAddress.getLocalHost.getHostName
        #
        hostname = "<getHostAddress>"
      }

      # Use these settings to bind a network interface to a different address
      # than artery expects messages at. This may be used when running Akka
      # nodes in a separated networks (under NATs or in containers). If canonical
      # and bind addresses are different, then network configuration that relays
      # communications from canonical to bind addresses is expected.
      bind {

        # Port to bind a network interface to. Can be set to a port number
        # of one of the following special values:
        #   0    random available port
        #   ""   akka.remote.artery.canonical.port
        #
        port = ""

        # Hostname to bind a network interface to. Can be set to an ip, hostname
        # or one of the following special values:
        #   "0.0.0.0"            all interfaces
        #   ""                   akka.remote.artery.canonical.hostname
        #   "<getHostAddress>"   InetAddress.getLocalHost.getHostAddress
        #   "<getHostName>"      InetAddress.getLocalHost.getHostName
        #
        hostname = ""

        # Time to wait for Aeron/TCP to bind
        bind-timeout = 3s
      }


      # Actor paths to use the large message stream for when a message
      # is sent to them over remoting. The large message stream dedicated
      # is separate from "normal" and system messages so that sending a
      # large message does not interfere with them.
      # Entries should be the full path to the actor. Wildcards in the form of "*"
      # can be supplied at any place and matches any name at that segment -
      # "/user/supervisor/actor/*" will match any direct child to actor,
      # while "/supervisor/*/child" will match any grandchild to "supervisor" that
      # has the name "child"
      # Entries have to be specified on both the sending and receiving side.
      # Messages sent to ActorSelections will not be passed through the large message
      # stream, to pass such messages through the large message stream the selections
      # but must be resolved to ActorRefs first.
      large-message-destinations = []

      # Enable untrusted mode, which discards inbound system messages, PossiblyHarmful and
      # ActorSelection messages. E.g. remote watch and remote deployment will not work.
      # ActorSelection messages can be enabled for specific paths with the trusted-selection-paths
      untrusted-mode = off

      # When 'untrusted-mode=on' inbound actor selections are by default discarded.
      # Actors with paths defined in this list are granted permission to receive actor
      # selections messages.
      # E.g. trusted-selection-paths = ["/user/receptionist", "/user/namingService"]
      trusted-selection-paths = []

      # If this is "on", all inbound remote messages will be logged at DEBUG level,
      # if off then they are not logged
      log-received-messages = off

      # If this is "on", all outbound remote messages will be logged at DEBUG level,
      # if off then they are not logged
      log-sent-messages = off

      advanced {

        # Maximum serialized message size, including header data.
        maximum-frame-size = 256 KiB

        # Direct byte buffers are reused in a pool with this maximum size.
        # Each buffer has the size of 'maximum-frame-size'.
        # This is not a hard upper limit on number of created buffers. Additional
        # buffers will be created if needed, e.g. when using many outbound
        # associations at the same time. Such additional buffers will be garbage
        # collected, which is not as efficient as reusing buffers in the pool.
        buffer-pool-size = 128

        # Maximum serialized message size for the large messages, including header data.
        # It is currently restricted to 1/8th the size of a term buffer that can be
        # configured by setting the 'aeron.term.buffer.length' system property.
        # See 'large-message-destinations'.
        maximum-large-frame-size = 2 MiB

        # Direct byte buffers for the large messages are reused in a pool with this maximum size.
        # Each buffer has the size of 'maximum-large-frame-size'.
        # See 'large-message-destinations'.
        # This is not a hard upper limit on number of created buffers. Additional
        # buffers will be created if needed, e.g. when using many outbound
        # associations at the same time. Such additional buffers will be garbage
        # collected, which is not as efficient as reusing buffers in the pool.
        large-buffer-pool-size = 32

        # For enabling testing features, such as blackhole in akka-remote-testkit.
        test-mode = off

        # Settings for the materializer that is used for the remote streams.
        materializer = ${akka.stream.materializer}

        # Remoting will use the given dispatcher for the ordinary and large message
        # streams.
        use-dispatcher = "akka.remote.default-remote-dispatcher"

        # Remoting will use the given dispatcher for the control stream.
        # It can be good to not use the same dispatcher for the control stream as
        # the dispatcher for the ordinary message stream so that heartbeat messages
        # are not disturbed.
        use-control-stream-dispatcher = "akka.actor.internal-dispatcher"


        # Total number of inbound lanes, shared among all inbound associations. A value
        # greater than 1 means that deserialization can be performed in parallel for
        # different destination actors. The selection of lane is based on consistent
        # hashing of the recipient ActorRef to preserve message ordering per receiver.
        # Lowest latency can be achieved with inbound-lanes=1 because of one less
        # asynchronous boundary.
        inbound-lanes = 4

        # Number of outbound lanes for each outbound association. A value greater than 1
        # means that serialization and other work can be performed in parallel for different
        # destination actors. The selection of lane is based on consistent hashing of the
        # recipient ActorRef to preserve message ordering per receiver. Note that messages
        # for different destination systems (hosts) are handled by different streams also
        # when outbound-lanes=1. Lowest latency can be achieved with outbound-lanes=1
        # because of one less asynchronous boundary.
        outbound-lanes = 1

        # Size of the send queue for outgoing messages. Messages will be dropped if
        # the queue becomes full. This may happen if you send a burst of many messages
        # without end-to-end flow control. Note that there is one such queue per
        # outbound association. The trade-off of using a larger queue size is that
        # it consumes more memory, since the queue is based on preallocated array with
        # fixed size.
        outbound-message-queue-size = 3072

        # Size of the send queue for outgoing control messages, such as system messages.
        # If this limit is reached the remote system is declared to be dead and its UID
        # marked as quarantined. Note that there is one such queue per outbound association.
        # It is a linked queue so it will not use more memory than needed but by increasing
        # too much you may risk OutOfMemoryError in the worst case.
        outbound-control-queue-size = 20000

        # Size of the send queue for outgoing large messages. Messages will be dropped if
        # the queue becomes full. This may happen if you send a burst of many messages
        # without end-to-end flow control. Note that there is one such queue per
        # outbound association.
        # It is a linked queue so it will not use more memory than needed but by increasing
        # too much you may risk OutOfMemoryError, especially since the message payload
        # of these messages may be large.
        outbound-large-message-queue-size = 256

        # This setting defines the maximum number of unacknowledged system messages
        # allowed for a remote system. If this limit is reached the remote system is
        # declared to be dead and its UID marked as quarantined.
        system-message-buffer-size = 20000

        # unacknowledged system messages are re-delivered with this interval
        system-message-resend-interval = 1 second



        # The timeout for outbound associations to perform the initial handshake.
        # This timeout must be greater than the 'image-liveness-timeout' when
        # transport is aeron-udp.
        handshake-timeout = 20 seconds

        # incomplete initial handshake attempt is retried with this interval
        handshake-retry-interval = 1 second

        # Handshake requests are performed periodically with this interval,
        # also after the handshake has been completed to be able to establish
        # a new session with a restarted destination system.
        inject-handshake-interval = 1 second


        # System messages that are not acknowledged after re-sending for this period are
        # dropped and will trigger quarantine. The value should be longer than the length
        # of a network partition that you need to survive.
        give-up-system-message-after = 6 hours

        # Outbound streams are stopped when they haven't been used for this duration.
        # They are started again when new messages are sent.
        stop-idle-outbound-after = 5 minutes

        # Outbound streams are quarantined when they haven't been used for this duration
        # to cleanup resources used by the association, such as compression tables.
        # This will cleanup association to crashed systems that didn't announce their
        # termination.
        # The value should be longer than the length of a network partition that you
        # need to survive.
        # The value must also be greater than stop-idle-outbound-after.
        # Once every 1/10 of this duration an extra handshake message will be sent.
        # Therfore it's also recommended to use a value that is greater than 10 times
        # the stop-idle-outbound-after, since otherwise the idle streams will not be
        # stopped.
        quarantine-idle-outbound-after = 6 hours

        # Stop outbound stream of a quarantined association after this idle timeout, i.e.
        # when not used any more.
        stop-quarantined-after-idle = 3 seconds

        # After catastrophic communication failures that could result in the loss of system
        # messages or after the remote DeathWatch triggers the remote system gets
        # quarantined to prevent inconsistent behavior.
        # This setting controls how long the quarantined association will be kept around
        # before being removed to avoid long-term memory leaks. It must be quarantined
        # and also unused for this duration before it's removed. When removed the historical
        # information about which UIDs that were quarantined for that hostname:port is
        # gone which could result in communication with a previously quarantined node
        # if it wakes up again. Therfore this shouldn't be set too low.
        remove-quarantined-association-after = 1 h

        # during ActorSystem termination the remoting will wait this long for
        # an acknowledgment by the destination system that flushing of outstanding
        # remote messages has been completed
        shutdown-flush-timeout = 1 second

        # See 'inbound-max-restarts'
        inbound-restart-timeout = 5 seconds

        # Max number of restarts within 'inbound-restart-timeout' for the inbound streams.
        # If more restarts occurs the ActorSystem will be terminated.
        inbound-max-restarts = 5

        # Retry outbound connection after this backoff.
        # Only used when transport is tcp or tls-tcp.
        outbound-restart-backoff = 1 second

        # See 'outbound-max-restarts'
        outbound-restart-timeout = 5 seconds

        # Max number of restarts within 'outbound-restart-timeout' for the outbound streams.
        # If more restarts occurs the ActorSystem will be terminated.
        outbound-max-restarts = 5

        # compression of common strings in remoting messages, like actor destinations, serializers etc
        compression {

          actor-refs {
            # Max number of compressed actor-refs
            # Note that compression tables are "rolling" (i.e. a new table replaces the old
            # compression table once in a while), and this setting is only about the total number
            # of compressions within a single such table.
            # Must be a positive natural number. Can be disabled with "off".
            max = 256

            # interval between new table compression advertisements.
            # this means the time during which we collect heavy-hitter data and then turn it into a compression table.
            advertisement-interval = 1 minute
          }
          manifests {
            # Max number of compressed manifests
            # Note that compression tables are "rolling" (i.e. a new table replaces the old
            # compression table once in a while), and this setting is only about the total number
            # of compressions within a single such table.
            # Must be a positive natural number. Can be disabled with "off".
            max = 256

            # interval between new table compression advertisements.
            # this means the time during which we collect heavy-hitter data and then turn it into a compression table.
            advertisement-interval = 1 minute
          }
        }

        # List of fully qualified class names of remote instruments which should
        # be initialized and used for monitoring of remote messages.
        # The class must extend akka.remote.artery.RemoteInstrument and
        # have a public constructor with empty parameters or one ExtendedActorSystem
        # parameter.
        # A new instance of RemoteInstrument will be created for each encoder and decoder.
        # It's only called from the stage, so if it dosn't delegate to any shared instance
        # it doesn't have to be thread-safe.
        # Refer to `akka.remote.artery.RemoteInstrument` for more information.
        instruments = ${?akka.remote.artery.advanced.instruments} []

        # Only used when transport is aeron-udp
        aeron {
          # Periodically log out all Aeron counters. See https://github.com/real-logic/aeron/wiki/Monitoring-and-Debugging#counters
          # Only used when transport is aeron-udp.
          log-aeron-counters = false

          # Controls whether to start the Aeron media driver in the same JVM or use external
          # process. Set to 'off' when using external media driver, and then also set the
          # 'aeron-dir'.
          # Only used when transport is aeron-udp.
          embedded-media-driver = on

          # Directory used by the Aeron media driver. It's mandatory to define the 'aeron-dir'
          # if using external media driver, i.e. when 'embedded-media-driver = off'.
          # Embedded media driver will use a this directory, or a temporary directory if this
          # property is not defined (empty).
          # Only used when transport is aeron-udp.
          aeron-dir = ""

          # Whether to delete aeron embedded driver directory upon driver stop.
          # Only used when transport is aeron-udp.
          delete-aeron-dir = yes

          # Level of CPU time used, on a scale between 1 and 10, during backoff/idle.
          # The tradeoff is that to have low latency more CPU time must be used to be
          # able to react quickly on incoming messages or send as fast as possible after
          # backoff backpressure.
          # Level 1 strongly prefer low CPU consumption over low latency.
          # Level 10 strongly prefer low latency over low CPU consumption.
          # Only used when transport is aeron-udp.
          idle-cpu-level = 5

          # messages that are not accepted by Aeron are dropped after retrying for this period
          # Only used when transport is aeron-udp.
          give-up-message-after = 60 seconds

          # Timeout after which aeron driver has not had keepalive messages
          # from a client before it considers the client dead.
          # Only used when transport is aeron-udp.
          client-liveness-timeout = 20 seconds

          # Timout after after which an uncommitted publication will be unblocked
          # Only used when transport is aeron-udp.
          publication-unblock-timeout = 40 seconds

          # Timeout for each the INACTIVE and LINGER stages an aeron image
          # will be retained for when it is no longer referenced.
          # This timeout must be less than the 'handshake-timeout'.
          # Only used when transport is aeron-udp.
          image-liveness-timeout = 10 seconds

          # Timeout after which the aeron driver is considered dead
          # if it does not update its C'n'C timestamp.
          # Only used when transport is aeron-udp.
          driver-timeout = 20 seconds
        }

        # Only used when transport is tcp or tls-tcp.
        tcp {
          # Timeout of establishing outbound connections.
          connection-timeout = 5 seconds

          # The local address that is used for the client side of the TCP connection.
          outbound-client-hostname = ""
        }

      }

      # SSL configuration that is used when transport=tls-tcp.
      ssl {
        # Factory of SSLEngine.
        # Must implement akka.remote.artery.tcp.SSLEngineProvider and have a public
        # constructor with an ActorSystem parameter.
        # The default ConfigSSLEngineProvider is configured by properties in section
        # akka.remote.artery.ssl.config-ssl-engine
        ssl-engine-provider = akka.remote.artery.tcp.ConfigSSLEngineProvider

        # Config of akka.remote.artery.tcp.ConfigSSLEngineProvider
        config-ssl-engine {

          # This is the Java Key Store used by the server connection
          key-store = "keystore"

          # This password is used for decrypting the key store
          # Use substitution from environment variables for passwords. Don't define
          # real passwords in config files. key-store-password=${SSL_KEY_STORE_PASSWORD}
          key-store-password = "changeme"

          # This password is used for decrypting the key
          # Use substitution from environment variables for passwords. Don't define
          # real passwords in config files. key-password=${SSL_KEY_PASSWORD}
          key-password = "changeme"

          # This is the Java Key Store used by the client connection
          trust-store = "truststore"

          # This password is used for decrypting the trust store
          # Use substitution from environment variables for passwords. Don't define
          # real passwords in config files. trust-store-password=${SSL_TRUST_STORE_PASSWORD}
          trust-store-password = "changeme"

          # Protocol to use for SSL encryption.
          protocol = "TLSv1.2"

          # Example: ["TLS_DHE_RSA_WITH_AES_128_GCM_SHA256", 
          #   "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",
          #   "TLS_DHE_RSA_WITH_AES_256_GCM_SHA384",
          #   "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384"]
          # When doing rolling upgrades, make sure to include both the algorithm used 
          # by old nodes and the preferred algorithm.
          # If you use a JDK 8 prior to 8u161 you need to install
          # the JCE Unlimited Strength Jurisdiction Policy Files to use AES 256.
          # More info here:
          # https://www.oracle.com/java/technologies/javase-jce-all-downloads.html
          enabled-algorithms = ["TLS_DHE_RSA_WITH_AES_256_GCM_SHA384",
            "TLS_RSA_WITH_AES_128_CBC_SHA"]

          # There are two options, and the default SecureRandom is recommended:
          # "" or "SecureRandom" => (default)
          # "SHA1PRNG" => Can be slow because of blocking issues on Linux
          #
          # Setting a value here may require you to supply the appropriate cipher
          # suite (see enabled-algorithms section above)
          random-number-generator = ""

          # Require mutual authentication between TLS peers
          #
          # Without mutual authentication only the peer that actively establishes a connection (TLS client side)
          # checks if the passive side (TLS server side) sends over a trusted certificate. With the flag turned on,
          # the passive side will also request and verify a certificate from the connecting peer.
          #
          # To prevent man-in-the-middle attacks this setting is enabled by default.
          require-mutual-authentication = on

          # Set this to `on` to verify hostnames with sun.security.util.HostnameChecker
          # If possible it is recommended to have this enabled. Hostname verification is designed for
          # situations where things locate each other by hostname, in scenarios where host names are dynamic
          # and not known up front it can make sense to have this disabled.
          hostname-verification = off
        }

        # Config of akka.remote.artery.tcp.ssl.RotatingKeysSSLEngineProvider
        # This engine provider reads PEM files from a mount point shared with the secret
        # manager. The constructed SSLContext is cached some time (configurable) so when
        # the credentials rotate the new credentials are eventually picked up.
        # By default mTLS is enabled.
        # This provider also includes a verification phase that runs after the TLS handshake
        # phase. In this verification, both peers run an authorization and verify they are
        # part of the same akka cluster. The verification happens via comparing the subject
        # names in the peer's certificate with the name on the own certificate so if you
        # use this SSLEngineProvider you should make sure all nodes on the cluster include
        # at least one common subject name (CN or SAN).
        # The Key setup this implementation supports has some limitations:
        #   1. the private key must be provided on a PKCS#1 or a non-encrypted PKCS#8 PEM-formatted file
        #   2. the private key must be be of an algorythm supported by `akka-pki` tools (e.g. "RSA", not "EC")
        #   3. the node certificate must be issued by a root CA (not an intermediate CA)
        #   4. both the node and the CA certificates must be provided in PEM-formatted files
        rotating-keys-engine {

          # This is a convention that people may follow if they wish to save themselves some configuration
          secret-mount-point = /var/run/secrets/akka-tls/rotating-keys-engine

          # The absolute path the PEM file with the private key.
          key-file = ${akka.remote.artery.ssl.rotating-keys-engine.secret-mount-point}/tls.key
          # The absolute path to the PEM file of the certificate for the private key above.
          cert-file = ${akka.remote.artery.ssl.rotating-keys-engine.secret-mount-point}/tls.crt
          # The absolute path to the PEM file of the certificate of the CA that emited
          # the node certificate above.
          ca-cert-file = ${akka.remote.artery.ssl.rotating-keys-engine.secret-mount-point}/ca.crt

          # There are two options, and the default SecureRandom is recommended:
          # "" or "SecureRandom" => (default)
          # "SHA1PRNG" => Can be slow because of blocking issues on Linux
          #
          # Setting a value here may require you to supply the appropriate cipher
          # suite (see enabled-algorithms section)
          random-number-generator = ""

          # Example: ["TLS_DHE_RSA_WITH_AES_128_GCM_SHA256",
          #   "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",
          #   "TLS_DHE_RSA_WITH_AES_256_GCM_SHA384",
          #   "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384"]
          # If you use a JDK 8 prior to 8u161 you need to install
          # the JCE Unlimited Strength Jurisdiction Policy Files to use AES 256.
          # More info here:
          # https://www.oracle.com/java/technologies/javase-jce-all-downloads.html
          enabled-algorithms = ["TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384"]

          # Protocol to use for SSL encryption.
          protocol = "TLSv1.2"

          # How long should an SSLContext instance be cached. When rotating keys and certificates,
          # there must a time overlap between the old certificate/key and the new ones. The
          # value of this setting should be lower than duration of that overlap.
          ssl-context-cache-ttl = 5m
        }
      }
    }
  }

}
#//#artery
