or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

core-api.mddiscovery-extension.mdindex.mdresolution-types.md
tile.json

discovery-extension.mddocs/

Discovery Extension System

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.

Capabilities

Discovery Extension Class

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)

Discovery Extension Object

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)

Configuration

The Discovery extension relies on configuration in application.conf to determine which implementations to load:

Default Discovery Method

akka.discovery {
  # Default discovery method - must be set to a valid method name
  method = "akka-dns"  # or "config", "aggregate", or custom implementation
}

Implementation Classes

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...
  }
}

Built-in Implementations

The extension supports loading these built-in discovery methods:

  • "akka-dns": DNS-based service discovery using SRV records and A/AAAA records
  • "config": Static configuration-based discovery from application.conf
  • "aggregate": Composite discovery that tries multiple methods in sequence

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")

Error Handling

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")
}