This tiny library provides mechanism of synchronization
via locks stored in Cassandra table.
This synchronization
is especially useful for preventing concurrent schema changes.
Sad that concurrent schema changes is not supported by Cassandra on it's own.
Basically this is a mutex implementation via records stored in cassandra. We insert record in order to acquire the lock and remove record when done. We also provide expiry duration per lock in case we failed to remove record. There is nice statement which ideally describes the concept.
def example(session: CassandraSession[IO]) = {
for {
cassandraSync <- CassandraSync.of(session, keyspace = "app")
result <- cassandraSync("id", expiry = 3.seconds, timeout = 10.seconds) {
// put your code here
// the lock in cassandra per id will ensure that your code runs strictly sequentially
}
} yield result
}
So you still need to create table to store locks there and better don't let app to do that, especially concurrently from different nodes. At Evolution Gaming this table is created along with keyspace creation by ops department.
CREATE TABLE IF NOT EXISTS keyspace.locks(
id TEXT PRIMARY KEY,
expiry_ms BIGINT,
timestamp TIMESTAMP,
metadata TEXT);
-- Acquire lock
INSERT INTO keyspace.locks (id, expiry_ms, timestamp, metadata) VALUES (?, ?, ?, ?)
IF NOT EXISTS USING TTL ?;
-- Release lock
-- This DELETE should also be a LWT op as mixing LWT and normal ops is prohibited
DELETE FROM keyspace.locks WHERE id = ? IF EXISTS;
addSbtPlugin("com.evolution" % "sbt-artifactory-plugin" % "0.0.2")
libraryDependencies += "com.evolutiongaming" %% "cassandra-sync" % latestVersion