/* * Copyright 2015 Heiko Seeberger * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package de.heikoseeberger.constructr.coordination import akka.Done import akka.actor.{ ActorSystem, Address } import scala.concurrent.Future import scala.concurrent.duration.FiniteDuration object Coordination { def apply(clusterName: String, system: ActorSystem): Coordination = try { val className = system.settings.config.getString("constructr.coordination.class-name") Class .forName(className) .getConstructor(classOf[String], classOf[ActorSystem]) .newInstance(clusterName, system) .asInstanceOf[Coordination] } catch { case _: NoSuchMethodException => throw new Exception( """|A Coordination implementation must provide a constructor with the following signature: |(clusterName: String, system: ActorSystem)""".stripMargin ) } } /** * Abstraction for a coordination service. Implementations must provide a constructor with the following signature: * `(prefix: String, clusterName: String, system: ActorSystem)`. */ trait Coordination { /** * Get the nodes. * * @return future of nodes */ def getNodes(): Future[Set[Address]] /** * Akquire a lock for bootstrapping the cluster (first node). * * @param self self node * @param ttl TTL for the lock * @return true, if lock could be akquired, else false */ def lock(self: Address, ttl: FiniteDuration): Future[Boolean] /** * Add self to the nodes. * * @param self self node * @param ttl TTL for the node entry * @return future signaling done */ def addSelf(self: Address, ttl: FiniteDuration): Future[Done] /** * Refresh entry for self. * * @param self self node * @param ttl TTL for the node entry * @return future signaling done */ def refresh(self: Address, ttl: FiniteDuration): Future[Done] }