Ticketing Java / Kotlinライブラリ
GitHub Maven Central1つのTicketBrokerが3つの呼び出しスタイルをまとめて提供します — Kotlinのコルーチンでは acquireを、Javaの非同期ではacquireAsync(CompletableFuture)を、Javaのブロッキングでは acquireBlockingを使います。どれを使っても、同じブローカー・同じ接続です。
リポジトリ
例
基本的な例
brokerはapplication起動時に1つ作って共有します。wait=0はqueueなしの即時試行1回で最大255秒、leaseは1〜250秒です。最後のminimum-work budgetは必須で0も可能です。秒未満は切り上げ、範囲外または正規化lease超過budgetは送信前に拒否し、clampしません。
Kotlin (coroutines):
val broker = TicketBroker.connect("127.0.0.1:5225")
broker.waitReady(Duration.ofSeconds(5))
val ticket = broker.acquire("key", Duration.ofSeconds(5), Duration.ofSeconds(30), Duration.ofSeconds(2))
val token = ticket.token
// In the same DB transaction: verify/update token high-water and perform the business write.
ticket.release()Java (blocking):
TicketBroker broker = TicketBroker.connect("127.0.0.1:5225");
broker.waitReadyBlocking(Duration.ofSeconds(5));
try (Ticket ticket = broker.acquireBlocking(
"key", Duration.ofSeconds(5), Duration.ofSeconds(30), Duration.ofSeconds(2))) {
long token = ticket.getToken();
// In the same DB transaction: verify/update token high-water and perform the business write.
}自動close/dropはbounded best-effort releaseです。結果が必要ならexplicit release APIを使います。tokenは同じDB transactionで保護対象writeをfenceしなければなりません。
知っておきたい挙動
- request byteを1つでも送った可能性があり確定応答を失うとIndeterminateです。同じownerで
Aを自動再送せず、callerはcritical sectionへ入りません。 - 送信前cancelはunsent、possible-send後cancelはsessionを閉じます。同時にgrant tokenをparseした場合はboundedなexact-token補償releaseを試みます。
M、全てのE、malformed/oversized/unknown responseはsession-fatalです。未確定possible-send acquireはIndeterminateです。Bはcapacityによる確定拒否で即時返却します。内部retryはなく、callerがapplication backoff後に新ownerで新acquireを開始できます。- explicit/compensating releaseはcall/enqueueから絶対5秒だけexact tokenを再試行します。
Rは成功、Nは既にないかcurrent tokenでない状態、最終応答なしは成功と推定せずerrorです。 - 正の保守的残り時間がありrequired work budgetを満たす場合だけTicketを返します。250秒超workは送信前にunsupportedです。
- tokenによるDB fencingは必須です。同じDB transactionで
token <= stored_high_waterを拒否し、high-water更新とbusiness writeを行ってcommit/rollback後にreleaseします。
セキュリティオプション(トークン · TLS)
すべてのオプションは任意です。tokenはサーバーのclient_tokensに合わせ、TLSはオフ / システム 信頼ストア / CA指定 / 検証省略(テスト専用)の4モードがあります。
val broker = TicketBroker.builder()
.addrs("10.0.0.1:5225", "10.0.0.2:5225", "10.0.0.3:5225")
.token("123")
.tls(TlsMode.SystemRoots)
// .tls(TlsMode.Ca("ca.crt"))
// .tls(TlsMode.InsecureSkipVerify)
.connect()Javaでは、静的ファクトリのTlsMode.systemRoots() / TlsMode.ca("ca.crt") / TlsMode.insecureSkipVerify()を使います。
サーバー側のトークン・TLS・クラスタ設定はTicketingサーバーデプロイ ページで生成できます。
Spring 仮想スレッド
Spring MVCを仮想スレッドで動かす場合は、JavaでもKotlinでも*Blocking関数を使います。 非suspendのコントローラーからはacquire(suspend)を呼べないため、Kotlinでも acquireBlockingが通常の経路です。コルーチンを経由せず応答でのみparkするので、 キャリアスレッドを占有しません。
@RestController
class OrderController(private val broker: TicketBroker) {
@PostMapping("/orders/{id}")
fun place(@PathVariable id: String): String {
broker.acquireBlocking("order-$id", Duration.ofSeconds(5), Duration.ofSeconds(30)).use {
// クリティカルセクション
}
return "ok"
}
}close()(try-with-resources / use)によるバックグラウンド返却は既定で仮想スレッド 実行機で動くため、固定サイズのプールで詰まりません。Spring管理の実行機を使うには 次のように渡します。
TicketBroker.builder()
.addrs("127.0.0.1:5225")
.executor(applicationTaskExecutor)
.connect()WebFluxやコルーチンコントローラーでは、これまで通りsuspend関数を使ってください。