or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

caching.mdindex.mdleader-election.mdlocking.mdshared-values.md

locking.mddocs/

0

# Distributed Locking

1

2

Distributed locking capabilities for coordinating access to shared resources across multiple processes and JVMs. Provides various locking mechanisms including mutexes, read-write locks, and semaphores with support for revocation and automatic cleanup.

3

4

## Capabilities

5

6

### InterProcessLock Interface

7

8

Base interface for all distributed locks providing consistent acquire/release semantics.

9

10

```java { .api }

11

/**

12

* Base interface for distributed locks that work across processes

13

*/

14

public interface InterProcessLock {

15

/**

16

* Acquire the lock, blocking until available

17

* @throws Exception if the lock cannot be acquired

18

*/

19

void acquire() throws Exception;

20

21

/**

22

* Acquire the lock within the given time period

23

* @param time maximum time to wait for the lock

24

* @param unit time unit of the time argument

25

* @return true if the lock was acquired, false otherwise

26

* @throws Exception if an error occurs during acquisition

27

*/

28

boolean acquire(long time, TimeUnit unit) throws Exception;

29

30

/**

31

* Release the lock

32

* @throws Exception if the lock cannot be released

33

*/

34

void release() throws Exception;

35

}

36

```

37

38

### InterProcessMutex

39

40

Re-entrant mutex implementation that works across JVMs. The same thread can acquire the lock multiple times.

41

42

```java { .api }

43

/**

44

* Re-entrant mutex that works across JVMs using ZooKeeper

45

*/

46

public class InterProcessMutex implements InterProcessLock {

47

/**

48

* Create a new InterProcessMutex

49

* @param client the curator client

50

* @param path the path to use for the lock

51

*/

52

public InterProcessMutex(CuratorFramework client, String path);

53

54

/**

55

* Acquire the lock, blocking until available

56

*/

57

public void acquire() throws Exception;

58

59

/**

60

* Acquire the lock within the given time period

61

* @param time maximum time to wait

62

* @param unit time unit

63

* @return true if acquired, false if timed out

64

*/

65

public boolean acquire(long time, TimeUnit unit) throws Exception;

66

67

/**

68

* Release the lock

69

*/

70

public void release() throws Exception;

71

72

/**

73

* Check if this mutex is acquired by the current thread

74

* @return true if acquired by current thread

75

*/

76

public boolean isAcquiredInThisProcess();

77

}

78

```

79

80

**Usage Example:**

81

82

```java

83

import org.apache.curator.framework.CuratorFramework;

84

import org.apache.curator.framework.recipes.locks.InterProcessMutex;

85

86

CuratorFramework client = // ... initialize client

87

InterProcessMutex lock = new InterProcessMutex(client, "/app/locks/resource");

88

89

try {

90

if (lock.acquire(10, TimeUnit.SECONDS)) {

91

// Critical section - only one process can execute this

92

System.out.println("Processing shared resource");

93

// ... do work

94

} else {

95

System.out.println("Could not acquire lock within 10 seconds");

96

}

97

} finally {

98

lock.release(); // Always release in finally block

99

}

100

```

101

102

### InterProcessSemaphoreMutex

103

104

Non-reentrant mutex implementation. Unlike InterProcessMutex, the same thread cannot acquire this lock multiple times.

105

106

```java { .api }

107

/**

108

* Non-reentrant mutex that works across JVMs

109

*/

110

public class InterProcessSemaphoreMutex implements InterProcessLock {

111

/**

112

* Create a new InterProcessSemaphoreMutex

113

* @param client the curator client

114

* @param path the path to use for the lock

115

*/

116

public InterProcessSemaphoreMutex(CuratorFramework client, String path);

117

118

public void acquire() throws Exception;

119

public boolean acquire(long time, TimeUnit unit) throws Exception;

120

public void release() throws Exception;

121

}

122

```

123

124

### InterProcessReadWriteLock

125

126

Read-write lock implementation allowing multiple readers or one writer across JVMs.

127

128

```java { .api }

129

/**

130

* Re-entrant read/write mutex that works across JVMs

131

*/

132

public class InterProcessReadWriteLock {

133

/**

134

* Create a new InterProcessReadWriteLock

135

* @param client the curator client

136

* @param lockPath the path to use for the lock

137

*/

138

public InterProcessReadWriteLock(CuratorFramework client, String lockPath);

139

140

/**

141

* Get the read lock portion of this lock

142

* @return read lock instance

143

*/

144

public InterProcessLock readLock();

145

146

/**

147

* Get the write lock portion of this lock

148

* @return write lock instance

149

*/

150

public InterProcessLock writeLock();

151

152

/**

153

* Nested class for read lock component

154

*/

155

public static class ReadLock implements InterProcessLock {

156

public void acquire() throws Exception;

157

public boolean acquire(long time, TimeUnit unit) throws Exception;

158

public void release() throws Exception;

159

}

160

161

/**

162

* Nested class for write lock component

163

*/

164

public static class WriteLock implements InterProcessLock {

165

public void acquire() throws Exception;

166

public boolean acquire(long time, TimeUnit unit) throws Exception;

167

public void release() throws Exception;

168

}

169

}

170

```

171

172

**Usage Example:**

173

174

```java

175

InterProcessReadWriteLock rwLock = new InterProcessReadWriteLock(client, "/app/locks/data");

176

InterProcessLock readLock = rwLock.readLock();

177

InterProcessLock writeLock = rwLock.writeLock();

178

179

// Multiple readers can acquire simultaneously

180

readLock.acquire();

181

try {

182

// Read shared data

183

System.out.println("Reading data...");

184

} finally {

185

readLock.release();

186

}

187

188

// Only one writer can acquire (and no readers)

189

writeLock.acquire();

190

try {

191

// Write shared data

192

System.out.println("Writing data...");

193

} finally {

194

writeLock.release();

195

}

196

```

197

198

### InterProcessMultiLock

199

200

Container for managing multiple locks as a single entity. All locks must be acquired for the multi-lock to be considered acquired.

201

202

```java { .api }

203

/**

204

* Container holding multiple locks and treating them as a single lock

205

*/

206

public class InterProcessMultiLock implements InterProcessLock {

207

/**

208

* Create a new InterProcessMultiLock

209

* @param locks list of locks to manage together

210

*/

211

public InterProcessMultiLock(List<InterProcessLock> locks);

212

213

/**

214

* Acquire all locks in the multi-lock

215

*/

216

public void acquire() throws Exception;

217

218

/**

219

* Acquire all locks within the given time period

220

*/

221

public boolean acquire(long time, TimeUnit unit) throws Exception;

222

223

/**

224

* Release all locks in the multi-lock

225

*/

226

public void release() throws Exception;

227

}

228

```

229

230

### InterProcessSemaphoreV2

231

232

Counting semaphore that works across JVMs, allowing a specified number of processes to acquire the semaphore.

233

234

```java { .api }

235

/**

236

* Counting semaphore that works across JVMs

237

*/

238

public class InterProcessSemaphoreV2 {

239

/**

240

* Create a new InterProcessSemaphoreV2

241

* @param client the curator client

242

* @param mutexPath the path to use for the semaphore

243

* @param maxLeases maximum number of simultaneous leases

244

*/

245

public InterProcessSemaphoreV2(CuratorFramework client, String mutexPath, int maxLeases);

246

247

/**

248

* Acquire a lease from the semaphore

249

* @return acquired lease, or null if not available

250

*/

251

public Lease acquire() throws Exception;

252

253

/**

254

* Acquire a lease within the given time period

255

*/

256

public Lease acquire(long time, TimeUnit unit) throws Exception;

257

258

/**

259

* Acquire multiple leases

260

* @param qty number of leases to acquire

261

* @return collection of acquired leases

262

*/

263

public Collection<Lease> acquire(int qty) throws Exception;

264

265

/**

266

* Get current available leases

267

* @return number of available leases

268

*/

269

public int availablePermits() throws Exception;

270

271

/**

272

* Return a lease to the semaphore

273

* @param lease the lease to return

274

*/

275

public void returnLease(Lease lease) throws Exception;

276

277

/**

278

* Return multiple leases

279

*/

280

public void returnAll(Collection<Lease> leases) throws Exception;

281

}

282

283

/**

284

* Represents a lease from a semaphore

285

*/

286

public class Lease implements Closeable {

287

/**

288

* Get the data associated with this lease

289

*/

290

public byte[] getData();

291

292

/**

293

* Get the node name for this lease

294

*/

295

public String getNodeName();

296

297

/**

298

* Close/return this lease

299

*/

300

public void close() throws IOException;

301

}

302

```

303

304

**Usage Example:**

305

306

```java

307

InterProcessSemaphoreV2 semaphore = new InterProcessSemaphoreV2(client, "/app/semaphore", 3);

308

309

Lease lease = semaphore.acquire(5, TimeUnit.SECONDS);

310

if (lease != null) {

311

try {

312

// Only 3 processes can be here simultaneously

313

System.out.println("Acquired semaphore lease");

314

// ... do work

315

} finally {

316

semaphore.returnLease(lease);

317

}

318

} else {

319

System.out.println("Could not acquire semaphore lease");

320

}

321

```

322

323

### Locker Utility

324

325

Utility class for try-with-resources lock acquisition pattern.

326

327

```java { .api }

328

/**

329

* Utility for using locks with try-with-resources

330

*/

331

public class Locker implements Closeable {

332

/**

333

* Create a new Locker for the given lock

334

* @param lock the lock to manage

335

* @param time maximum time to wait for acquisition

336

* @param unit time unit

337

*/

338

public Locker(InterProcessLock lock, long time, TimeUnit unit) throws Exception;

339

340

/**

341

* Release the managed lock

342

*/

343

public void close() throws IOException;

344

}

345

```

346

347

**Usage Example:**

348

349

```java

350

InterProcessMutex lock = new InterProcessMutex(client, "/app/locks/resource");

351

352

try (Locker locker = new Locker(lock, 10, TimeUnit.SECONDS)) {

353

// Lock is automatically acquired here and released when leaving the try block

354

System.out.println("Lock acquired, doing work...");

355

// ... do work

356

} // Lock is automatically released here

357

```

358

359

### Revocable Interface

360

361

Interface for locks that can be revoked by external processes.

362

363

```java { .api }

364

/**

365

* Interface for locks that can be revoked

366

*/

367

public interface Revocable<T> {

368

/**

369

* Make the lock revocable with the given listener

370

* @param listener listener to be called when revocation is requested

371

*/

372

void makeRevocable(RevocationListener<T> listener);

373

}

374

375

/**

376

* Listener interface for lock revocation events

377

*/

378

public interface RevocationListener<T> {

379

/**

380

* Called when revocation is requested

381

* @param forLock the lock being revoked

382

*/

383

void revocationRequested(T forLock);

384

}

385

```