Service discovery API for distributed Akka applications to locate and connect to other services in dynamic environments.
Extension system for loading and managing service discovery implementations with support for multiple discovery methods and configuration-based selection. The Discovery extension integrates with Akka's extension system to provide a singleton service discovery manager per ActorSystem.
The main extension class that manages service discovery implementations and provides access to the default configured discovery method.
/**
* Discovery extension for managing service discovery implementations
* Integrates with Akka's extension system as a singleton per ActorSystem
*/
final class Discovery extends Extension {
/**
* Get the default ServiceDiscovery implementation
* Configured via akka.discovery.method in application.conf
* @return ServiceDiscovery instance
* @throws IllegalArgumentException if no default method is configured
*/
def discovery: ServiceDiscovery
/**
* Load a specific ServiceDiscovery implementation by method name
* Implementation classes are configured via akka.discovery.[method].class
* Instances are cached - subsequent calls with same method return same instance
* @param method Discovery method name (e.g., "akka-dns", "config", "aggregate")
* @return ServiceDiscovery instance for the specified method
* @throws IllegalArgumentException if method is not properly configured
*/
def loadServiceDiscovery(method: String): ServiceDiscovery
}Usage Examples:
import akka.actor.ActorSystem
import akka.discovery.Discovery
implicit val system = ActorSystem("my-system")
// Get default discovery implementation (from akka.discovery.method config)
val defaultDiscovery = Discovery(system).discovery
// Load specific discovery implementations
val dnsDiscovery = Discovery(system).loadServiceDiscovery("akka-dns")
val configDiscovery = Discovery(system).loadServiceDiscovery("config")
val aggregateDiscovery = Discovery(system).loadServiceDiscovery("aggregate")
// Use different implementations for different purposes
val webServices = dnsDiscovery.lookup("web-service", 3.seconds)
val localServices = configDiscovery.lookup("local-service", 1.second)The companion object implementing Akka's ExtensionId pattern for integration with the actor system extension mechanism.
/**
* Extension ID and provider for Discovery extension
* Implements Akka's extension pattern for singleton per ActorSystem
*/
object Discovery extends ExtensionId[Discovery] with ExtensionIdProvider {
/**
* Get Discovery extension instance for ActorSystem
* @param system ActorSystem instance
* @return Discovery extension singleton for this system
*/
def apply(system: ActorSystem): Discovery
/**
* Alternative way to get Discovery extension instance
* @param system ActorSystem instance
* @return Discovery extension singleton for this system
*/
def get(system: ActorSystem): Discovery
/**
* Get Discovery extension from ClassicActorSystemProvider
* @param system ClassicActorSystemProvider instance
* @return Discovery extension singleton for this system
*/
def get(system: ClassicActorSystemProvider): Discovery
/**
* Extension lookup method (part of ExtensionIdProvider)
* @return This Discovery extension ID
*/
def lookup: Discovery.type
/**
* Create new Discovery extension instance (part of ExtensionId)
* @param system ExtendedActorSystem instance
* @return New Discovery extension instance
*/
def createExtension(system: ExtendedActorSystem): Discovery
}Usage Examples:
import akka.actor.{ActorSystem, ClassicActorSystemProvider}
import akka.discovery.Discovery
// Standard ActorSystem
val system = ActorSystem("my-system")
val discovery1 = Discovery(system)
val discovery2 = Discovery.get(system)
// discovery1 and discovery2 are the same instance
// From ClassicActorSystemProvider
val provider: ClassicActorSystemProvider = system
val discovery3 = Discovery.get(provider)The Discovery extension relies on configuration in application.conf to determine which implementations to load:
akka.discovery {
# Default discovery method - must be set to a valid method name
method = "akka-dns" # or "config", "aggregate", or custom implementation
}akka.discovery {
# DNS-based discovery (built-in)
akka-dns {
class = "akka.discovery.dns.DnsServiceDiscovery"
}
# Configuration-based discovery (built-in)
config {
class = "akka.discovery.config.ConfigServiceDiscovery"
services-path = "akka.discovery.config.services"
}
# Aggregate discovery (built-in)
aggregate {
class = "akka.discovery.aggregate.AggregateServiceDiscovery"
discovery-methods = ["akka-dns", "config"]
}
# Custom implementation example
my-custom {
class = "com.example.MyServiceDiscovery"
# custom configuration properties...
}
}The extension supports loading these built-in discovery methods:
Configuration Examples:
// application.conf configuration affects Discovery behavior
import akka.actor.ActorSystem
import akka.discovery.Discovery
// With akka.discovery.method = "akka-dns"
val system1 = ActorSystem("dns-system")
val dnsDiscovery = Discovery(system1).discovery
// Returns DNS-based discovery implementation
// With akka.discovery.method = "aggregate"
val system2 = ActorSystem("aggregate-system")
val aggregateDiscovery = Discovery(system2).discovery
// Returns aggregate discovery that tries multiple methods
// Load specific methods regardless of default
val specificDns = Discovery(system1).loadServiceDiscovery("akka-dns")
val specificConfig = Discovery(system1).loadServiceDiscovery("config")import akka.discovery.Discovery
try {
// Will throw IllegalArgumentException if method not configured
val invalidDiscovery = Discovery(system).loadServiceDiscovery("non-existent")
} catch {
case _: IllegalArgumentException =>
println("Discovery method not properly configured")
}
try {
// Will throw IllegalArgumentException if akka.discovery.method = "<method>" (placeholder)
val defaultDiscovery = Discovery(system).discovery
} catch {
case e: IllegalArgumentException if e.getMessage.contains("No default service discovery") =>
println("Default discovery method not configured - set akka.discovery.method")
case e: IllegalArgumentException if e.getMessage.contains("Illegal") =>
println("Discovery implementation class incompatible or missing constructor")
}Install with Tessl CLI
npx tessl i tessl/maven-com-typesafe-akka--akka-discovery-2-12