Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -353,8 +353,8 @@ lazy val lernaUtilSequence = lernaModule("lerna-util-sequence")
.settings(
libraryDependencies ++= Seq(
Dependencies.DataStax.cassandraDriverCore,
Dependencies.Akka.actor,
Dependencies.Akka.testKit % Test,
Dependencies.Akka.actorTyped,
Dependencies.Akka.actorTestKitTyped % Test,
),
)

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
# typed ActorSystem 対応
# ClassicActorSystemProvider は typed/classic 両方の ActorSystem が継承しているので compileエラーにはならない
# ※ Akka 2.6 以上のみ対応

# abstract method system()akka.actor.ActorSystem in class lerna.util.sequence.CassandraSequenceFactory has a different result type in current version, where it is akka.actor.ClassicActorSystemProvider rather than akka.actor.ActorSystem
ProblemFilters.exclude[IncompatibleResultTypeProblem]("lerna.util.sequence.CassandraSequenceFactory.system")
# abstract method system()akka.actor.ClassicActorSystemProvider in class lerna.util.sequence.CassandraSequenceFactory is present only in current version
ProblemFilters.exclude[ReversedMissingMethodProblem]("lerna.util.sequence.CassandraSequenceFactory.system")


# Behavior 化 にともなう内部 Actor の Message 変更
# - 同一JVM 内でのみ使用されシリアライズされることはない
# - ライブラリ(lerna.util.sequence)内部でのみ使用され外部から直接参照されることはない
# method copy(scala.Option)lerna.util.sequence.SequenceFactoryWorker#GenerateSequence in class lerna.util.sequence.SequenceFactoryWorker#GenerateSequence does not have a correspondent in current version
ProblemFilters.exclude[DirectMissingMethodProblem]("lerna.util.sequence.SequenceFactoryWorker#GenerateSequence.copy")
# method this(scala.Option)Unit in class lerna.util.sequence.SequenceFactoryWorker#GenerateSequence does not have a correspondent in current version
ProblemFilters.exclude[DirectMissingMethodProblem]("lerna.util.sequence.SequenceFactoryWorker#GenerateSequence.this")
# the type hierarchy of object lerna.util.sequence.SequenceFactoryWorker#GenerateSequence is different in current version. Missing types {scala.runtime.AbstractFunction1}
ProblemFilters.exclude[MissingTypesProblem]("lerna.util.sequence.SequenceFactoryWorker$GenerateSequence$")
# method apply(scala.Option)lerna.util.sequence.SequenceFactoryWorker#GenerateSequence in object lerna.util.sequence.SequenceFactoryWorker#GenerateSequence does not have a correspondent in current version
ProblemFilters.exclude[DirectMissingMethodProblem]("lerna.util.sequence.SequenceFactoryWorker#GenerateSequence.apply")
# method unapply(lerna.util.sequence.SequenceFactoryWorker#GenerateSequence)scala.Option in object lerna.util.sequence.SequenceFactoryWorker#GenerateSequence has a different generic signature in current version, where it is (Llerna/util/sequence/SequenceFactoryWorker$GenerateSequence;)Lscala/Option<Lscala/Tuple2<Lscala/Option<Ljava/lang/String;>;Lakka/actor/typed/ActorRef<Llerna/util/sequence/SequenceFactoryWorker$SequenceGenerated;>;>;>; rather than (Llerna/util/sequence/SequenceFactoryWorker$GenerateSequence;)Lscala/Option<Lscala/Option<Ljava/lang/String;>;>;. See https://github.com/lightbend/mima#incompatiblesignatureproblem
ProblemFilters.exclude[IncompatibleSignatureProblem]("lerna.util.sequence.SequenceFactoryWorker#GenerateSequence.unapply")
# interface lerna.util.sequence.SequenceStore#DomainEvent does not have a correspondent in current version
ProblemFilters.exclude[MissingClassProblem]("lerna.util.sequence.SequenceStore$DomainEvent")
# method copy(scala.math.BigInt,Int,scala.Option)lerna.util.sequence.SequenceStore#InitialReserveSequence in class lerna.util.sequence.SequenceStore#InitialReserveSequence does not have a correspondent in current version
ProblemFilters.exclude[DirectMissingMethodProblem]("lerna.util.sequence.SequenceStore#InitialReserveSequence.copy")
# method this(scala.math.BigInt,Int,scala.Option)Unit in class lerna.util.sequence.SequenceStore#InitialReserveSequence does not have a correspondent in current version
ProblemFilters.exclude[DirectMissingMethodProblem]("lerna.util.sequence.SequenceStore#InitialReserveSequence.this")
# the type hierarchy of object lerna.util.sequence.SequenceStore#InitialReserveSequence is different in current version. Missing types {scala.runtime.AbstractFunction3}
ProblemFilters.exclude[MissingTypesProblem]("lerna.util.sequence.SequenceStore$InitialReserveSequence$")
# method apply(scala.math.BigInt,Int,scala.Option)lerna.util.sequence.SequenceStore#InitialReserveSequence in object lerna.util.sequence.SequenceStore#InitialReserveSequence does not have a correspondent in current version
ProblemFilters.exclude[DirectMissingMethodProblem]("lerna.util.sequence.SequenceStore#InitialReserveSequence.apply")
# method unapply(lerna.util.sequence.SequenceStore#InitialReserveSequence)scala.Option in object lerna.util.sequence.SequenceStore#InitialReserveSequence has a different generic signature in current version, where it is (Llerna/util/sequence/SequenceStore$InitialReserveSequence;)Lscala/Option<Lscala/Tuple4<Lscala/math/BigInt;Ljava/lang/Object;Lscala/Option<Ljava/lang/String;>;Lakka/actor/typed/ActorRef<Llerna/util/sequence/SequenceStore$ReservationResponse;>;>;>; rather than (Llerna/util/sequence/SequenceStore$InitialReserveSequence;)Lscala/Option<Lscala/Tuple3<Lscala/math/BigInt;Ljava/lang/Object;Lscala/Option<Ljava/lang/String;>;>;>;. See https://github.com/lightbend/mima#incompatiblesignatureproblem
ProblemFilters.exclude[IncompatibleSignatureProblem]("lerna.util.sequence.SequenceStore#InitialReserveSequence.unapply")
# the type hierarchy of class lerna.util.sequence.SequenceStore#InitialSequenceReserved is different in current version. Missing types {lerna.util.sequence.SequenceStore$DomainEvent}
ProblemFilters.exclude[MissingTypesProblem]("lerna.util.sequence.SequenceStore$InitialSequenceReserved")
# the type hierarchy of object lerna.util.sequence.SequenceStore#ReservationFailed is different in current version. Missing types {lerna.util.sequence.SequenceStore$DomainEvent}
ProblemFilters.exclude[MissingTypesProblem]("lerna.util.sequence.SequenceStore$ReservationFailed$")
# method copy(scala.math.BigInt,Int,scala.Option)lerna.util.sequence.SequenceStore#ReserveSequence in class lerna.util.sequence.SequenceStore#ReserveSequence does not have a correspondent in current version
ProblemFilters.exclude[DirectMissingMethodProblem]("lerna.util.sequence.SequenceStore#ReserveSequence.copy")
# method this(scala.math.BigInt,Int,scala.Option)Unit in class lerna.util.sequence.SequenceStore#ReserveSequence does not have a correspondent in current version
ProblemFilters.exclude[DirectMissingMethodProblem]("lerna.util.sequence.SequenceStore#ReserveSequence.this")
# the type hierarchy of object lerna.util.sequence.SequenceStore#ReserveSequence is different in current version. Missing types {scala.runtime.AbstractFunction3}
ProblemFilters.exclude[MissingTypesProblem]("lerna.util.sequence.SequenceStore$ReserveSequence$")
# method apply(scala.math.BigInt,Int,scala.Option)lerna.util.sequence.SequenceStore#ReserveSequence in object lerna.util.sequence.SequenceStore#ReserveSequence does not have a correspondent in current version
ProblemFilters.exclude[DirectMissingMethodProblem]("lerna.util.sequence.SequenceStore#ReserveSequence.apply")
# method unapply(lerna.util.sequence.SequenceStore#ReserveSequence)scala.Option in object lerna.util.sequence.SequenceStore#ReserveSequence has a different generic signature in current version, where it is (Llerna/util/sequence/SequenceStore$ReserveSequence;)Lscala/Option<Lscala/Tuple4<Lscala/math/BigInt;Ljava/lang/Object;Lscala/Option<Ljava/lang/String;>;Lakka/actor/typed/ActorRef<Llerna/util/sequence/SequenceStore$ReservationResponse;>;>;>; rather than (Llerna/util/sequence/SequenceStore$ReserveSequence;)Lscala/Option<Lscala/Tuple3<Lscala/math/BigInt;Ljava/lang/Object;Lscala/Option<Ljava/lang/String;>;>;>;. See https://github.com/lightbend/mima#incompatiblesignatureproblem
ProblemFilters.exclude[IncompatibleSignatureProblem]("lerna.util.sequence.SequenceStore#ReserveSequence.unapply")
# method copy(scala.math.BigInt,Int,scala.Option)lerna.util.sequence.SequenceStore#ResetReserveSequence in class lerna.util.sequence.SequenceStore#ResetReserveSequence does not have a correspondent in current version
ProblemFilters.exclude[DirectMissingMethodProblem]("lerna.util.sequence.SequenceStore#ResetReserveSequence.copy")
# method this(scala.math.BigInt,Int,scala.Option)Unit in class lerna.util.sequence.SequenceStore#ResetReserveSequence does not have a correspondent in current version
ProblemFilters.exclude[DirectMissingMethodProblem]("lerna.util.sequence.SequenceStore#ResetReserveSequence.this")
# the type hierarchy of object lerna.util.sequence.SequenceStore#ResetReserveSequence is different in current version. Missing types {scala.runtime.AbstractFunction3}
ProblemFilters.exclude[MissingTypesProblem]("lerna.util.sequence.SequenceStore$ResetReserveSequence$")
# method apply(scala.math.BigInt,Int,scala.Option)lerna.util.sequence.SequenceStore#ResetReserveSequence in object lerna.util.sequence.SequenceStore#ResetReserveSequence does not have a correspondent in current version
ProblemFilters.exclude[DirectMissingMethodProblem]("lerna.util.sequence.SequenceStore#ResetReserveSequence.apply")
# method unapply(lerna.util.sequence.SequenceStore#ResetReserveSequence)scala.Option in object lerna.util.sequence.SequenceStore#ResetReserveSequence has a different generic signature in current version, where it is (Llerna/util/sequence/SequenceStore$ResetReserveSequence;)Lscala/Option<Lscala/Tuple4<Lscala/math/BigInt;Ljava/lang/Object;Lscala/Option<Ljava/lang/String;>;Lakka/actor/typed/ActorRef<Llerna/util/sequence/SequenceStore$ReservationResponse;>;>;>; rather than (Llerna/util/sequence/SequenceStore$ResetReserveSequence;)Lscala/Option<Lscala/Tuple3<Lscala/math/BigInt;Ljava/lang/Object;Lscala/Option<Ljava/lang/String;>;>;>;. See https://github.com/lightbend/mima#incompatiblesignatureproblem
ProblemFilters.exclude[IncompatibleSignatureProblem]("lerna.util.sequence.SequenceStore#ResetReserveSequence.unapply")
# the type hierarchy of class lerna.util.sequence.SequenceStore#SequenceReserved is different in current version. Missing types {lerna.util.sequence.SequenceStore$DomainEvent}
ProblemFilters.exclude[MissingTypesProblem]("lerna.util.sequence.SequenceStore$SequenceReserved")
# the type hierarchy of class lerna.util.sequence.SequenceStore#SequenceReset is different in current version. Missing types {lerna.util.sequence.SequenceStore$DomainEvent}
ProblemFilters.exclude[MissingTypesProblem]("lerna.util.sequence.SequenceStore$SequenceReset")
# the type hierarchy of class lerna.util.sequence.SequenceStore#SessionOpened is different in current version. Missing types {lerna.util.sequence.SequenceStore$DomainEvent}
ProblemFilters.exclude[MissingTypesProblem]("lerna.util.sequence.SequenceStore$SessionOpened")
# the type hierarchy of class lerna.util.sequence.SequenceStore#SessionPrepared is different in current version. Missing types {lerna.util.sequence.SequenceStore$DomainEvent}
ProblemFilters.exclude[MissingTypesProblem]("lerna.util.sequence.SequenceStore$SessionPrepared")
14 changes: 14 additions & 0 deletions lerna-util-sequence/src/main/resources/reference.conf
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,20 @@ lerna.util.sequence {
# 確保したシーケンスをインメモリに持つ、ワーカーを開放するまでの時間
worker.idle-timeout = 10s

# ワーカーで処理中の際にメッセージをバッファーする上限
# 上限を超えた場合、Actorは再起動し処理中のメッセージは失われ(レスポンスされない)タイムアウトする
# 参考: https://doc.akka.io/docs/akka/current/typed/stash.html
# 処理要求が多すぎてバッファーが耐えられなくなると akka.actor.typed.javadsl.StashOverflowException が throw される。
# その場合、 stash-capacity を大きくするべき。ただし、メモリ使用量は増加する。
worker.stash-capacity = 1000

# ストアで処理中の際にメッセージをバッファーする上限
# 上限を超えた場合、Actorは再起動し処理中のメッセージは失われ(レスポンスされない)タイムアウトする
# 参考: https://doc.akka.io/docs/akka/current/typed/stash.html
# 処理要求が多すぎてバッファーが耐えられなくなると akka.actor.typed.javadsl.StashOverflowException が throw される。
# その場合、 stash-capacity を大きくするべき。ただし、メモリ使用量は増加する。
store.stash-capacity = 1000

cassandra {
tenants = {
// example = ${lerna.util.sequence.cassandra.default}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,16 @@ package lerna.util.sequence
import java.net.URLEncoder
import java.nio.charset.StandardCharsets

import akka.actor.ActorSystem
import akka.pattern.ask
import akka.actor.ClassicActorSystemProvider
import akka.actor.typed.ActorSystem
import akka.actor.typed.scaladsl.AskPattern._
import akka.actor.typed.scaladsl.adapter._
import akka.util.Timeout
import com.typesafe.config.Config
import lerna.log.AppLogging
import lerna.util.tenant.Tenant

import scala.concurrent.Future
import scala.concurrent.{ ExecutionContextExecutor, Future }

/** A sequence factory using Cassandra
*
Expand Down Expand Up @@ -58,7 +60,9 @@ abstract class CassandraSequenceFactory extends SequenceFactory with AppLogging

/** The actor system that is used for creating internal actors
*/
val system: ActorSystem
val system: ClassicActorSystemProvider

implicit private def typedSystem: ActorSystem[Nothing] = system.classicSystem.toTyped

/** The configuration that is used for reading settings
*/
Expand All @@ -84,14 +88,14 @@ abstract class CassandraSequenceFactory extends SequenceFactory with AppLogging

private[this] implicit val generateTimeout: Timeout = Timeout(sequenceConfig.generateTimeout)

import system.dispatcher
private[this] implicit def ec: ExecutionContextExecutor = typedSystem.executionContext

private[this] def encode(str: String) = URLEncoder.encode(str, StandardCharsets.UTF_8.name)

private[this] val sequenceFactoryMap = supportedTenants.map { implicit tenant =>
val actor = system.actorOf(
val actor = typedSystem.systemActorOf(
SequenceFactorySupervisor
.props(seqId, maxSequenceValue = maxSequence, reservationAmount = sequenceCacheSize),
.apply(seqId, maxSequenceValue = maxSequence, reservationAmount = sequenceCacheSize),
name = encode(s"SequenceFactory-$seqId-${tenant.id}"),
)

Expand All @@ -102,8 +106,9 @@ abstract class CassandraSequenceFactory extends SequenceFactory with AppLogging
sequenceFactoryMap
.get(tenant)
.map { sequenceFactory =>
(sequenceFactory ? SequenceFactoryWorker.GenerateSequence(subId))
.mapTo[SequenceFactoryWorker.SequenceGenerated].map(_.value)
sequenceFactory
.ask(replyTo => SequenceFactoryWorker.GenerateSequence(subId, replyTo))
.map(_.value)
}
.getOrElse {
// `supportedTenants` の値は外部に漏れるとまずい場合があるので message に入れていない
Expand Down
Loading