From 13c0a0cdb18855665d9d32f321f210cccb5d9b0e Mon Sep 17 00:00:00 2001 From: Arnaud Date: Tue, 25 Feb 2025 10:03:20 +0100 Subject: [PATCH 1/7] Define raises for async pragma --- datastore/datastore.nim | 14 +++++++------- datastore/fsds.nim | 12 ++++++------ datastore/leveldb/leveldbds.nim | 12 ++++++------ datastore/mountedds.nim | 12 ++++++------ datastore/sql/sqliteds.nim | 12 ++++++------ datastore/tieredds.nim | 24 ++++++++++++++---------- datastore/typedds.nim | 12 ++++++------ 7 files changed, 51 insertions(+), 47 deletions(-) diff --git a/datastore/datastore.nim b/datastore/datastore.nim index b038165..31abb1f 100644 --- a/datastore/datastore.nim +++ b/datastore/datastore.nim @@ -16,22 +16,22 @@ type Modify* = Function[?seq[byte], Future[?seq[byte]]] ModifyGet* = Function[?seq[byte], Future[(?seq[byte], seq[byte])]] -method has*(self: Datastore, key: Key): Future[?!bool] {.base, gcsafe, locks: "unknown".} = +method has*(self: Datastore, key: Key): Future[?!bool] {.base, gcsafe, async: (raises: [CancelledError]), locks: "unknown".} = raiseAssert("Not implemented!") -method delete*(self: Datastore, key: Key): Future[?!void] {.base, gcsafe, locks: "unknown".} = +method delete*(self: Datastore, key: Key): Future[?!void] {.base, gcsafe, async: (raises: [CancelledError]), locks: "unknown".} = raiseAssert("Not implemented!") -method delete*(self: Datastore, keys: seq[Key]): Future[?!void] {.base, gcsafe, locks: "unknown".} = +method delete*(self: Datastore, keys: seq[Key]): Future[?!void] {.base, gcsafe, async: (raises: [CancelledError]), locks: "unknown".} = raiseAssert("Not implemented!") -method get*(self: Datastore, key: Key): Future[?!seq[byte]] {.base, gcsafe, locks: "unknown".} = +method get*(self: Datastore, key: Key): Future[?!seq[byte]] {.base, gcsafe, async: (raises: [CancelledError]), locks: "unknown".} = raiseAssert("Not implemented!") -method put*(self: Datastore, key: Key, data: seq[byte]): Future[?!void] {.base, gcsafe, locks: "unknown".} = +method put*(self: Datastore, key: Key, data: seq[byte]): Future[?!void] {.base, gcsafe, async: (raises: [CancelledError]), locks: "unknown".} = raiseAssert("Not implemented!") -method put*(self: Datastore, batch: seq[BatchEntry]): Future[?!void] {.base, gcsafe, locks: "unknown".} = +method put*(self: Datastore, batch: seq[BatchEntry]): Future[?!void] {.base, gcsafe, async: (raises: [CancelledError]), locks: "unknown".} = raiseAssert("Not implemented!") method close*(self: Datastore): Future[?!void] {.base, async, locks: "unknown".} = @@ -43,7 +43,7 @@ method query*( raiseAssert("Not implemented!") -proc contains*(self: Datastore, key: Key): Future[bool] {.async.} = +proc contains*(self: Datastore, key: Key): Future[bool] {.async: (raises: [CancelledError]).} = return (await self.has(key)) |? false method modify*(self: Datastore, key: Key, fn: Modify): Future[?!void] {.base, gcsafe, locks: "unknown".} = diff --git a/datastore/fsds.nim b/datastore/fsds.nim index 7599fce..407c2c3 100644 --- a/datastore/fsds.nim +++ b/datastore/fsds.nim @@ -65,10 +65,10 @@ proc path*(self: FSDatastore, key: Key): ?!string = return success fullname -method has*(self: FSDatastore, key: Key): Future[?!bool] {.async.} = +method has*(self: FSDatastore, key: Key): Future[?!bool] {.async: (raises: [CancelledError]).} = return self.path(key).?fileExists() -method delete*(self: FSDatastore, key: Key): Future[?!void] {.async.} = +method delete*(self: FSDatastore, key: Key): Future[?!void] {.async: (raises: [CancelledError]).} = without path =? self.path(key), error: return failure error @@ -82,7 +82,7 @@ method delete*(self: FSDatastore, key: Key): Future[?!void] {.async.} = return success() -method delete*(self: FSDatastore, keys: seq[Key]): Future[?!void] {.async.} = +method delete*(self: FSDatastore, keys: seq[Key]): Future[?!void] {.async: (raises: [CancelledError]).} = for key in keys: if err =? (await self.delete(key)).errorOption: return failure err @@ -119,7 +119,7 @@ proc readFile*(self: FSDatastore, path: string): ?!seq[byte] = except CatchableError as e: return failure e -method get*(self: FSDatastore, key: Key): Future[?!seq[byte]] {.async.} = +method get*(self: FSDatastore, key: Key): Future[?!seq[byte]] {.async: (raises: [CancelledError]).} = without path =? self.path(key), error: return failure error @@ -132,7 +132,7 @@ method get*(self: FSDatastore, key: Key): Future[?!seq[byte]] {.async.} = method put*( self: FSDatastore, key: Key, - data: seq[byte]): Future[?!void] {.async.} = + data: seq[byte]): Future[?!void] {.async: (raises: [CancelledError]).} = without path =? self.path(key), error: return failure error @@ -147,7 +147,7 @@ method put*( method put*( self: FSDatastore, - batch: seq[BatchEntry]): Future[?!void] {.async.} = + batch: seq[BatchEntry]): Future[?!void] {.async: (raises: [CancelledError]).} = for entry in batch: if err =? (await self.put(entry.key, entry.data)).errorOption: diff --git a/datastore/leveldb/leveldbds.nim b/datastore/leveldb/leveldbds.nim index afa07ae..14d6a09 100644 --- a/datastore/leveldb/leveldbds.nim +++ b/datastore/leveldb/leveldbds.nim @@ -20,27 +20,27 @@ type db: LevelDb locks: TableRef[Key, AsyncLock] -method has*(self: LevelDbDatastore, key: Key): Future[?!bool] {.async.} = +method has*(self: LevelDbDatastore, key: Key): Future[?!bool] {.async: (raises: [CancelledError]).} = try: let str = self.db.get($key) return success(str.isSome) except LevelDbException as e: return failure("LevelDbDatastore.has exception: " & e.msg) -method delete*(self: LevelDbDatastore, key: Key): Future[?!void] {.async.} = +method delete*(self: LevelDbDatastore, key: Key): Future[?!void] {.async: (raises: [CancelledError]).} = try: self.db.delete($key, sync = true) return success() except LevelDbException as e: return failure("LevelDbDatastore.delete exception: " & e.msg) -method delete*(self: LevelDbDatastore, keys: seq[Key]): Future[?!void] {.async.} = +method delete*(self: LevelDbDatastore, keys: seq[Key]): Future[?!void] {.async: (raises: [CancelledError]).} = for key in keys: if err =? (await self.delete(key)).errorOption: return failure(err.msg) return success() -method get*(self: LevelDbDatastore, key: Key): Future[?!seq[byte]] {.async.} = +method get*(self: LevelDbDatastore, key: Key): Future[?!seq[byte]] {.async: (raises: [CancelledError]).} = try: let str = self.db.get($key) if not str.isSome: @@ -50,7 +50,7 @@ method get*(self: LevelDbDatastore, key: Key): Future[?!seq[byte]] {.async.} = except LevelDbException as e: return failure("LevelDbDatastore.get exception: " & $e.msg) -method put*(self: LevelDbDatastore, key: Key, data: seq[byte]): Future[?!void] {.async.} = +method put*(self: LevelDbDatastore, key: Key, data: seq[byte]): Future[?!void] {.async: (raises: [CancelledError]).} = try: let str = string.fromBytes(data) self.db.put($key, str) @@ -58,7 +58,7 @@ method put*(self: LevelDbDatastore, key: Key, data: seq[byte]): Future[?!void] { except LevelDbException as e: return failure("LevelDbDatastore.put exception: " & $e.msg) -method put*(self: LevelDbDatastore, batch: seq[BatchEntry]): Future[?!void] {.async.} = +method put*(self: LevelDbDatastore, batch: seq[BatchEntry]): Future[?!void] {.async: (raises: [CancelledError]).} = try: let b = newBatch() for entry in batch: diff --git a/datastore/mountedds.nim b/datastore/mountedds.nim index 5be8511..02a58d4 100644 --- a/datastore/mountedds.nim +++ b/datastore/mountedds.nim @@ -63,7 +63,7 @@ proc dispatch( method has*( self: MountedDatastore, - key: Key): Future[?!bool] {.async.} = + key: Key): Future[?!bool] {.async: (raises: [CancelledError]).} = without mounted =? self.dispatch(key): return failure "No mounted datastore found" @@ -72,7 +72,7 @@ method has*( method delete*( self: MountedDatastore, - key: Key): Future[?!void] {.async.} = + key: Key): Future[?!void] {.async: (raises: [CancelledError]).} = without mounted =? self.dispatch(key), error: return failure(error) @@ -81,7 +81,7 @@ method delete*( method delete*( self: MountedDatastore, - keys: seq[Key]): Future[?!void] {.async.} = + keys: seq[Key]): Future[?!void] {.async: (raises: [CancelledError]).} = for key in keys: if err =? (await self.delete(key)).errorOption: @@ -91,7 +91,7 @@ method delete*( method get*( self: MountedDatastore, - key: Key): Future[?!seq[byte]] {.async.} = + key: Key): Future[?!seq[byte]] {.async: (raises: [CancelledError]).} = without mounted =? self.dispatch(key), error: return failure(error) @@ -101,7 +101,7 @@ method get*( method put*( self: MountedDatastore, key: Key, - data: seq[byte]): Future[?!void] {.async.} = + data: seq[byte]): Future[?!void] {.async: (raises: [CancelledError]).} = without mounted =? self.dispatch(key), error: return failure(error) @@ -110,7 +110,7 @@ method put*( method put*( self: MountedDatastore, - batch: seq[BatchEntry]): Future[?!void] {.async.} = + batch: seq[BatchEntry]): Future[?!void] {.async: (raises: [CancelledError]).} = for entry in batch: if err =? (await self.put(entry.key, entry.data)).errorOption: diff --git a/datastore/sql/sqliteds.nim b/datastore/sql/sqliteds.nim index 8f16f07..bfffcf6 100644 --- a/datastore/sql/sqliteds.nim +++ b/datastore/sql/sqliteds.nim @@ -146,7 +146,7 @@ method modify*(self: SQLiteDatastore, key: Key, fn: Modify): Future[?!void] {.as else: return success() -method has*(self: SQLiteDatastore, key: Key): Future[?!bool] {.async.} = +method has*(self: SQLiteDatastore, key: Key): Future[?!bool] {.async: (raises: [CancelledError]).} = var exists = false @@ -158,10 +158,10 @@ method has*(self: SQLiteDatastore, key: Key): Future[?!bool] {.async.} = return success exists -method delete*(self: SQLiteDatastore, key: Key): Future[?!void] {.async.} = +method delete*(self: SQLiteDatastore, key: Key): Future[?!void] {.async: (raises: [CancelledError]).} = return self.db.deleteStmt.exec((key.id)) -method delete*(self: SQLiteDatastore, keys: seq[Key]): Future[?!void] {.async.} = +method delete*(self: SQLiteDatastore, keys: seq[Key]): Future[?!void] {.async: (raises: [CancelledError]).} = if err =? self.db.beginStmt.exec().errorOption: return failure(err) @@ -177,7 +177,7 @@ method delete*(self: SQLiteDatastore, keys: seq[Key]): Future[?!void] {.async.} return success() -method get*(self: SQLiteDatastore, key: Key): Future[?!seq[byte]] {.async.} = +method get*(self: SQLiteDatastore, key: Key): Future[?!seq[byte]] {.async: (raises: [CancelledError]).} = # see comment in ./filesystem_datastore re: finer control of memory # allocation in `method get`, could apply here as well if bytes were read # incrementally with `sqlite3_blob_read` @@ -197,10 +197,10 @@ method get*(self: SQLiteDatastore, key: Key): Future[?!seq[byte]] {.async.} = return success bytes -method put*(self: SQLiteDatastore, key: Key, data: seq[byte]): Future[?!void] {.async.} = +method put*(self: SQLiteDatastore, key: Key, data: seq[byte]): Future[?!void] {.async: (raises: [CancelledError]).} = return self.db.putStmt.exec((key.id, data, initVersion, timestamp())) -method put*(self: SQLiteDatastore, batch: seq[BatchEntry]): Future[?!void] {.async.} = +method put*(self: SQLiteDatastore, batch: seq[BatchEntry]): Future[?!void] {.async: (raises: [CancelledError]).} = if err =? self.db.beginStmt.exec().errorOption: return failure err diff --git a/datastore/tieredds.nim b/datastore/tieredds.nim index 36cbc72..80a3d01 100644 --- a/datastore/tieredds.nim +++ b/datastore/tieredds.nim @@ -28,7 +28,7 @@ proc stores*(self: TieredDatastore): seq[Datastore] = method has*( self: TieredDatastore, - key: Key): Future[?!bool] {.async.} = + key: Key): Future[?!bool] {.async: (raises: [CancelledError]).} = for store in self.stores: without res =? (await store.has(key)), err: @@ -41,32 +41,34 @@ method has*( method delete*( self: TieredDatastore, - key: Key): Future[?!void] {.async.} = + key: Key): Future[?!void] {.async: (raises: [CancelledError]).} = let pending = await allFinished(self.stores.mapIt(it.delete(key))) for fut in pending: - if fut.read().isErr: return fut.read() + without res =? fut.read().catch, error: + return failure error return success() method delete*( self: TieredDatastore, - keys: seq[Key]): Future[?!void] {.async.} = + keys: seq[Key]): Future[?!void] {.async: (raises: [CancelledError]).} = for key in keys: let pending = await allFinished(self.stores.mapIt(it.delete(key))) for fut in pending: - if fut.read().isErr: return fut.read() + without res =? fut.read().catch, error: + return failure error return success() method get*( self: TieredDatastore, - key: Key): Future[?!seq[byte]] {.async.} = + key: Key): Future[?!seq[byte]] {.async: (raises: [CancelledError]).} = var bytes: seq[byte] @@ -91,26 +93,28 @@ method get*( method put*( self: TieredDatastore, key: Key, - data: seq[byte]): Future[?!void] {.async.} = + data: seq[byte]): Future[?!void] {.async: (raises: [CancelledError]).} = let pending = await allFinished(self.stores.mapIt(it.put(key, data))) for fut in pending: - if fut.read().isErr: return fut.read() + without res =? fut.read().catch, error: + return failure error return success() method put*( self: TieredDatastore, - batch: seq[BatchEntry]): Future[?!void] {.async.} = + batch: seq[BatchEntry]): Future[?!void] {.async: (raises: [CancelledError]).} = for entry in batch: let pending = await allFinished(self.stores.mapIt(it.put(entry.key, entry.data))) for fut in pending: - if fut.read().isErr: return fut.read() + without res =? fut.read().catch, error: + return failure error return success() diff --git a/datastore/typedds.nim b/datastore/typedds.nim index 21dc2a2..cf7b0f0 100644 --- a/datastore/typedds.nim +++ b/datastore/typedds.nim @@ -71,16 +71,16 @@ template requireEncoder*(T: typedesc): untyped = {.error: "provide an encoder: `proc encode(a: " & $T & "): seq[byte]`".} # Original Datastore API -proc has*(self: TypedDatastore, key: Key): Future[?!bool] {.async.} = +proc has*(self: TypedDatastore, key: Key): Future[?!bool] {.async: (raises: [CancelledError]).} = await self.ds.has(key) -proc contains*(self: TypedDatastore, key: Key): Future[bool] {.async.} = +proc contains*(self: TypedDatastore, key: Key): Future[bool] {.async: (raises: [CancelledError]).} = return (await self.ds.has(key)) |? false -proc delete*(self: TypedDatastore, key: Key): Future[?!void] {.async.} = +proc delete*(self: TypedDatastore, key: Key): Future[?!void] {.async: (raises: [CancelledError]).} = await self.ds.delete(key) -proc delete*(self: TypedDatastore, keys: seq[Key]): Future[?!void] {.async.} = +proc delete*(self: TypedDatastore, keys: seq[Key]): Future[?!void] {.async: (raises: [CancelledError]).} = await self.ds.delete(keys) proc close*(self: TypedDatastore): Future[?!void] {.async.} = @@ -90,12 +90,12 @@ proc close*(self: TypedDatastore): Future[?!void] {.async.} = proc init*(T: type TypedDatastore, ds: Datastore): T = TypedDatastore(ds: ds) -proc put*[T](self: TypedDatastore, key: Key, t: T): Future[?!void] {.async.} = +proc put*[T](self: TypedDatastore, key: Key, t: T): Future[?!void] {.async: (raises: [CancelledError]).} = requireEncoder(T) await self.ds.put(key, t.encode) -proc get*[T](self: TypedDatastore, key: Key): Future[?!T] {.async.} = +proc get*[T](self: TypedDatastore, key: Key): Future[?!T] {.async: (raises: [CancelledError]).} = requireDecoder(T) without bytes =? await self.ds.get(key), error: From 42e4f530bff0162765c649adf1d5481c58b53cdb Mon Sep 17 00:00:00 2001 From: Arnaud Date: Tue, 25 Feb 2025 11:01:10 +0100 Subject: [PATCH 2/7] Add errors to raises async pragam --- datastore/datastore.nim | 8 +++--- datastore/defaultimpl.nim | 5 ++-- datastore/fsds.nim | 9 +++--- datastore/leveldb/leveldbds.nim | 8 +++--- datastore/mountedds.nim | 6 ++-- datastore/sql/sqliteds.nim | 8 +++--- datastore/tieredds.nim | 49 +++++++++++++++++++++++---------- datastore/typedds.nim | 6 ++-- 8 files changed, 59 insertions(+), 40 deletions(-) diff --git a/datastore/datastore.nim b/datastore/datastore.nim index 31abb1f..0bab3ad 100644 --- a/datastore/datastore.nim +++ b/datastore/datastore.nim @@ -34,19 +34,19 @@ method put*(self: Datastore, key: Key, data: seq[byte]): Future[?!void] {.base, method put*(self: Datastore, batch: seq[BatchEntry]): Future[?!void] {.base, gcsafe, async: (raises: [CancelledError]), locks: "unknown".} = raiseAssert("Not implemented!") -method close*(self: Datastore): Future[?!void] {.base, async, locks: "unknown".} = +method close*(self: Datastore): Future[?!void] {.base, async: (raises: [CancelledError]), locks: "unknown".} = raiseAssert("Not implemented!") method query*( self: Datastore, - query: Query): Future[?!QueryIter] {.base, gcsafe.} = + query: Query): Future[?!QueryIter] {.base, gcsafe, async: (raises: [CancelledError]).} = raiseAssert("Not implemented!") proc contains*(self: Datastore, key: Key): Future[bool] {.async: (raises: [CancelledError]).} = return (await self.has(key)) |? false -method modify*(self: Datastore, key: Key, fn: Modify): Future[?!void] {.base, gcsafe, locks: "unknown".} = +method modify*(self: Datastore, key: Key, fn: Modify): Future[?!void] {.base, gcsafe, async: (raises: [CancelledError, AsyncLockError]), locks: "unknown".} = ## Concurrently safe way of modifying the value associated with the `key`. ## ## Same as `modifyGet`, but this takes `fn` that doesn't produce any auxillary value. @@ -54,7 +54,7 @@ method modify*(self: Datastore, key: Key, fn: Modify): Future[?!void] {.base, gc raiseAssert("Not implemented!") -method modifyGet*(self: Datastore, key: Key, fn: ModifyGet): Future[?!seq[byte]] {.base, gcsafe, locks: "unknown".} = +method modifyGet*(self: Datastore, key: Key, fn: ModifyGet): Future[?!seq[byte]] {.base, gcsafe, async: (raises: [CancelledError, AsyncLockError]), locks: "unknown".} = ## Concurrently safe way of updating value associated with the `key`. Returns auxillary value on ## successful update. ## diff --git a/datastore/defaultimpl.nim b/datastore/defaultimpl.nim index be7178a..c4ae77b 100644 --- a/datastore/defaultimpl.nim +++ b/datastore/defaultimpl.nim @@ -11,10 +11,9 @@ proc defaultModifyGetImpl*( lock: AsyncLock, key: Key, fn: ModifyGet - ): Future[?!seq[byte]] {.async.} = + ): Future[?!seq[byte]] {.async: (raises: [CancelledError, AsyncLockError]).} = # Default implementation, serializes all modify operations using provided lock # - await lock.acquire() try: @@ -53,7 +52,7 @@ proc defaultModifyImpl*( lock: AsyncLock, key: Key, fn: Modify - ): Future[?!void] {.async.} = + ): Future[?!void] {.async: (raises: [CancelledError, AsyncLockError]).} = proc wrappedFn(maybeValue: ?seq[byte]): Future[(?seq[byte], seq[byte])] {.async.} = let res = await fn(maybeValue) let ignoredAux = newSeq[byte]() diff --git a/datastore/fsds.nim b/datastore/fsds.nim index 407c2c3..a7fdb83 100644 --- a/datastore/fsds.nim +++ b/datastore/fsds.nim @@ -163,12 +163,12 @@ proc dirWalker(path: string): (iterator: string {.raises: [Defect], gcsafe.}) = except CatchableError as exc: raise newException(Defect, exc.msg) -method close*(self: FSDatastore): Future[?!void] {.async.} = +method close*(self: FSDatastore): Future[?!void] {.async: (raises: [CancelledError]).} = return success() method query*( self: FSDatastore, - query: Query): Future[?!QueryIter] {.async.} = + query: Query): Future[?!QueryIter] {.async: (raises: [CancelledError]).} = without path =? self.path(query.key), error: return failure error @@ -221,7 +221,7 @@ method query*( method modifyGet*( self: FSDatastore, key: Key, - fn: ModifyGet): Future[?!seq[byte]] {.async.} = + fn: ModifyGet): Future[?!seq[byte]] {.async: (raises: [CancelledError, AsyncLockError]).} = var lock: AsyncLock try: lock = self.locks.mgetOrPut(key, newAsyncLock()) @@ -233,8 +233,9 @@ method modifyGet*( method modify*( self: FSDatastore, key: Key, - fn: Modify): Future[?!void] {.async.} = + fn: Modify): Future[?!void] {.async: (raises: [CancelledError, AsyncLockError]).} = var lock: AsyncLock + try: lock = self.locks.mgetOrPut(key, newAsyncLock()) return await defaultModifyImpl(self, lock, key, fn) diff --git a/datastore/leveldb/leveldbds.nim b/datastore/leveldb/leveldbds.nim index 14d6a09..e438470 100644 --- a/datastore/leveldb/leveldbds.nim +++ b/datastore/leveldb/leveldbds.nim @@ -68,7 +68,7 @@ method put*(self: LevelDbDatastore, batch: seq[BatchEntry]): Future[?!void] {.as except LevelDbException as e: return failure("LevelDbDatastore.put (batch) exception: " & $e.msg) -method close*(self: LevelDbDatastore): Future[?!void] {.async.} = +method close*(self: LevelDbDatastore): Future[?!void] {.async: (raises: [CancelledError]).} = try: self.db.close() return success() @@ -84,7 +84,7 @@ proc getQueryString(query: Query): string = method query*( self: LevelDbDatastore, - query: Query): Future[?!QueryIter] {.async, gcsafe.} = + query: Query): Future[?!QueryIter] {.async: (raises: [CancelledError]), gcsafe.} = if not (query.sort == SortOrder.Assending): return failure("LevelDbDatastore.query: query.sort is not SortOrder.Ascending. Unsupported.") @@ -125,7 +125,7 @@ method query*( method modifyGet*( self: LevelDbDatastore, key: Key, - fn: ModifyGet): Future[?!seq[byte]] {.async.} = + fn: ModifyGet): Future[?!seq[byte]] {.async: (raises: [CancelledError, AsyncLockError]).} = var lock: AsyncLock try: lock = self.locks.mgetOrPut(key, newAsyncLock()) @@ -137,7 +137,7 @@ method modifyGet*( method modify*( self: LevelDbDatastore, key: Key, - fn: Modify): Future[?!void] {.async.} = + fn: Modify): Future[?!void] {.async: (raises: [CancelledError, AsyncLockError]).} = var lock: AsyncLock try: lock = self.locks.mgetOrPut(key, newAsyncLock()) diff --git a/datastore/mountedds.nim b/datastore/mountedds.nim index 02a58d4..f4de063 100644 --- a/datastore/mountedds.nim +++ b/datastore/mountedds.nim @@ -121,7 +121,7 @@ method put*( method modifyGet*( self: MountedDatastore, key: Key, - fn: ModifyGet): Future[?!seq[byte]] {.async.} = + fn: ModifyGet): Future[?!seq[byte]] {.async: (raises: [CancelledError, AsyncLockError]).} = without mounted =? self.dispatch(key), error: return failure(error) @@ -131,14 +131,14 @@ method modifyGet*( method modify*( self: MountedDatastore, key: Key, - fn: Modify): Future[?!void] {.async.} = + fn: Modify): Future[?!void] {.async: (raises: [CancelledError, AsyncLockError]).} = without mounted =? self.dispatch(key), error: return failure(error) return await mounted.store.store.modify(mounted.relative, fn) -method close*(self: MountedDatastore): Future[?!void] {.async.} = +method close*(self: MountedDatastore): Future[?!void] {.async: (raises: [CancelledError]).} = for s in self.stores.values: discard await s.store.close() diff --git a/datastore/sql/sqliteds.nim b/datastore/sql/sqliteds.nim index bfffcf6..ccd9e92 100644 --- a/datastore/sql/sqliteds.nim +++ b/datastore/sql/sqliteds.nim @@ -40,7 +40,7 @@ proc newRollbackError(rbErr: ref CatchableError, opErrMsg: string): ref Rollback proc newRollbackError(rbErr: ref CatchableError, opErr: ref CatchableError): ref RollbackError = return newRollbackError(rbErr, opErr) -method modifyGet*(self: SQLiteDatastore, key: Key, fn: ModifyGet): Future[?!seq[byte]] {.async.} = +method modifyGet*(self: SQLiteDatastore, key: Key, fn: ModifyGet): Future[?!seq[byte]] {.async: (raises: [CancelledError, AsyncLockError]).} = var retriesLeft = 100 # allows reasonable concurrency, avoids infinite loop aux: seq[byte] @@ -135,7 +135,7 @@ method modifyGet*(self: SQLiteDatastore, key: Key, fn: ModifyGet): Future[?!seq[ return success(aux) -method modify*(self: SQLiteDatastore, key: Key, fn: Modify): Future[?!void] {.async.} = +method modify*(self: SQLiteDatastore, key: Key, fn: Modify): Future[?!void] {.async: (raises: [CancelledError, AsyncLockError]).} = proc wrappedFn(maybeValue: ?seq[byte]): Future[(?seq[byte], seq[byte])] {.async.} = let res = await fn(maybeValue) let ignoredAux = newSeq[byte]() @@ -216,14 +216,14 @@ method put*(self: SQLiteDatastore, batch: seq[BatchEntry]): Future[?!void] {.asy return success() -method close*(self: SQLiteDatastore): Future[?!void] {.async.} = +method close*(self: SQLiteDatastore): Future[?!void] {.async: (raises: [CancelledError]).} = self.db.close() return success() method query*( self: SQLiteDatastore, - query: Query): Future[?!QueryIter] {.async.} = + query: Query): Future[?!QueryIter] {.async: (raises: [CancelledError]).} = var iter = QueryIter() diff --git a/datastore/tieredds.nim b/datastore/tieredds.nim index 80a3d01..2118320 100644 --- a/datastore/tieredds.nim +++ b/datastore/tieredds.nim @@ -47,8 +47,11 @@ method delete*( pending = await allFinished(self.stores.mapIt(it.delete(key))) for fut in pending: - without res =? fut.read().catch, error: - return failure error + try: + if fut.read().isErr: + return fut.read() + except FuturePendingError as err: + return failure err return success() @@ -61,8 +64,11 @@ method delete*( pending = await allFinished(self.stores.mapIt(it.delete(key))) for fut in pending: - without res =? fut.read().catch, error: - return failure error + try: + if fut.read().isErr: + return fut.read() + except FuturePendingError as err: + return failure err return success() @@ -99,8 +105,11 @@ method put*( pending = await allFinished(self.stores.mapIt(it.put(key, data))) for fut in pending: - without res =? fut.read().catch, error: - return failure error + try: + if fut.read().isErr: + return fut.read() + except FuturePendingError as err: + return failure err return success() @@ -113,15 +122,18 @@ method put*( pending = await allFinished(self.stores.mapIt(it.put(entry.key, entry.data))) for fut in pending: - without res =? fut.read().catch, error: - return failure error + try: + if fut.read().isErr: + return fut.read() + except FuturePendingError as err: + return failure err return success() method modifyGet*( self: TieredDatastore, key: Key, - fn: ModifyGet): Future[?!seq[byte]] {.async.} = + fn: ModifyGet): Future[?!seq[byte]] {.async: (raises: [CancelledError, AsyncLockError]).} = let pending = await allFinished(self.stores.mapIt(it.modifyGet(key, fn))) @@ -129,23 +141,30 @@ method modifyGet*( var aux = newSeq[byte]() for fut in pending: - if fut.read().isErr: - return fut.read() - else: - aux.add(fut.read().get) + try: + if fut.read().isErr: + return fut.read() + else: + aux.add(fut.read().get) + except FuturePendingError as err: + return failure err return success(aux) method modify*( self: TieredDatastore, key: Key, - fn: Modify): Future[?!void] {.async.} = + fn: Modify): Future[?!void] {.async: (raises: [CancelledError, AsyncLockError]).} = let pending = await allFinished(self.stores.mapIt(it.modify(key, fn))) for fut in pending: - if fut.read().isErr: return fut.read() + try: + if fut.read().isErr: + return fut.read() + except FuturePendingError as err: + return failure err return success() diff --git a/datastore/typedds.nim b/datastore/typedds.nim index cf7b0f0..4bf76c2 100644 --- a/datastore/typedds.nim +++ b/datastore/typedds.nim @@ -102,7 +102,7 @@ proc get*[T](self: TypedDatastore, key: Key): Future[?!T] {.async: (raises: [Can return failure(error) return T.decode(bytes) -proc modify*[T](self: TypedDatastore, key: Key, fn: Modify[T]): Future[?!void] {.async.} = +proc modify*[T](self: TypedDatastore, key: Key, fn: Modify[T]): Future[?!void] {.async: (raises: [CancelledError, AsyncLockError]).} = requireDecoder(T) requireEncoder(T) @@ -123,7 +123,7 @@ proc modify*[T](self: TypedDatastore, key: Key, fn: Modify[T]): Future[?!void] { await self.ds.modify(key, wrappedFn) -proc modifyGet*[T, U](self: TypedDatastore, key: Key, fn: ModifyGet[T, U]): Future[?!U] {.async.} = +proc modifyGet*[T, U](self: TypedDatastore, key: Key, fn: ModifyGet[T, U]): Future[?!U] {.async: (raises: [CancelledError, AsyncLockError]).} = requireDecoder(T) requireEncoder(T) requireEncoder(U) @@ -153,7 +153,7 @@ proc modifyGet*[T, U](self: TypedDatastore, key: Key, fn: ModifyGet[T, U]): Futu return U.decode(auxBytes) -proc query*[T](self: TypedDatastore, q: Query): Future[?!QueryIter[T]] {.async.} = +proc query*[T](self: TypedDatastore, q: Query): Future[?!QueryIter[T]] {.async: (raises: [CancelledError]).} = requireDecoder(T) without dsIter =? await self.ds.query(q), error: From 9586f95ccda54aadafe1b59e7ea0a352983e995b Mon Sep 17 00:00:00 2001 From: Arnaud Date: Tue, 25 Feb 2025 11:21:01 +0100 Subject: [PATCH 3/7] Do not propagate AsyncLockError --- datastore/datastore.nim | 4 ++-- datastore/defaultimpl.nim | 9 ++++++--- datastore/fsds.nim | 4 ++-- datastore/leveldb/leveldbds.nim | 4 ++-- datastore/mountedds.nim | 4 ++-- datastore/sql/sqliteds.nim | 4 ++-- datastore/tieredds.nim | 4 ++-- datastore/typedds.nim | 4 ++-- 8 files changed, 20 insertions(+), 17 deletions(-) diff --git a/datastore/datastore.nim b/datastore/datastore.nim index 0bab3ad..b89d38f 100644 --- a/datastore/datastore.nim +++ b/datastore/datastore.nim @@ -46,7 +46,7 @@ method query*( proc contains*(self: Datastore, key: Key): Future[bool] {.async: (raises: [CancelledError]).} = return (await self.has(key)) |? false -method modify*(self: Datastore, key: Key, fn: Modify): Future[?!void] {.base, gcsafe, async: (raises: [CancelledError, AsyncLockError]), locks: "unknown".} = +method modify*(self: Datastore, key: Key, fn: Modify): Future[?!void] {.base, gcsafe, async: (raises: [CancelledError]), locks: "unknown".} = ## Concurrently safe way of modifying the value associated with the `key`. ## ## Same as `modifyGet`, but this takes `fn` that doesn't produce any auxillary value. @@ -54,7 +54,7 @@ method modify*(self: Datastore, key: Key, fn: Modify): Future[?!void] {.base, gc raiseAssert("Not implemented!") -method modifyGet*(self: Datastore, key: Key, fn: ModifyGet): Future[?!seq[byte]] {.base, gcsafe, async: (raises: [CancelledError, AsyncLockError]), locks: "unknown".} = +method modifyGet*(self: Datastore, key: Key, fn: ModifyGet): Future[?!seq[byte]] {.base, gcsafe, async: (raises: [CancelledError]), locks: "unknown".} = ## Concurrently safe way of updating value associated with the `key`. Returns auxillary value on ## successful update. ## diff --git a/datastore/defaultimpl.nim b/datastore/defaultimpl.nim index c4ae77b..72cd4b3 100644 --- a/datastore/defaultimpl.nim +++ b/datastore/defaultimpl.nim @@ -11,7 +11,7 @@ proc defaultModifyGetImpl*( lock: AsyncLock, key: Key, fn: ModifyGet - ): Future[?!seq[byte]] {.async: (raises: [CancelledError, AsyncLockError]).} = + ): Future[?!seq[byte]] {.async: (raises: [CancelledError]).} = # Default implementation, serializes all modify operations using provided lock # await lock.acquire() @@ -45,14 +45,17 @@ proc defaultModifyGetImpl*( return aux.success finally: - lock.release() + try: + lock.release() + except AsyncLockError as err: + return failure(err) proc defaultModifyImpl*( self: Datastore, lock: AsyncLock, key: Key, fn: Modify - ): Future[?!void] {.async: (raises: [CancelledError, AsyncLockError]).} = + ): Future[?!void] {.async: (raises: [CancelledError]).} = proc wrappedFn(maybeValue: ?seq[byte]): Future[(?seq[byte], seq[byte])] {.async.} = let res = await fn(maybeValue) let ignoredAux = newSeq[byte]() diff --git a/datastore/fsds.nim b/datastore/fsds.nim index a7fdb83..a073b4c 100644 --- a/datastore/fsds.nim +++ b/datastore/fsds.nim @@ -221,7 +221,7 @@ method query*( method modifyGet*( self: FSDatastore, key: Key, - fn: ModifyGet): Future[?!seq[byte]] {.async: (raises: [CancelledError, AsyncLockError]).} = + fn: ModifyGet): Future[?!seq[byte]] {.async: (raises: [CancelledError]).} = var lock: AsyncLock try: lock = self.locks.mgetOrPut(key, newAsyncLock()) @@ -233,7 +233,7 @@ method modifyGet*( method modify*( self: FSDatastore, key: Key, - fn: Modify): Future[?!void] {.async: (raises: [CancelledError, AsyncLockError]).} = + fn: Modify): Future[?!void] {.async: (raises: [CancelledError]).} = var lock: AsyncLock try: diff --git a/datastore/leveldb/leveldbds.nim b/datastore/leveldb/leveldbds.nim index e438470..fc83764 100644 --- a/datastore/leveldb/leveldbds.nim +++ b/datastore/leveldb/leveldbds.nim @@ -125,7 +125,7 @@ method query*( method modifyGet*( self: LevelDbDatastore, key: Key, - fn: ModifyGet): Future[?!seq[byte]] {.async: (raises: [CancelledError, AsyncLockError]).} = + fn: ModifyGet): Future[?!seq[byte]] {.async: (raises: [CancelledError]).} = var lock: AsyncLock try: lock = self.locks.mgetOrPut(key, newAsyncLock()) @@ -137,7 +137,7 @@ method modifyGet*( method modify*( self: LevelDbDatastore, key: Key, - fn: Modify): Future[?!void] {.async: (raises: [CancelledError, AsyncLockError]).} = + fn: Modify): Future[?!void] {.async: (raises: [CancelledError]).} = var lock: AsyncLock try: lock = self.locks.mgetOrPut(key, newAsyncLock()) diff --git a/datastore/mountedds.nim b/datastore/mountedds.nim index f4de063..cebcc4a 100644 --- a/datastore/mountedds.nim +++ b/datastore/mountedds.nim @@ -121,7 +121,7 @@ method put*( method modifyGet*( self: MountedDatastore, key: Key, - fn: ModifyGet): Future[?!seq[byte]] {.async: (raises: [CancelledError, AsyncLockError]).} = + fn: ModifyGet): Future[?!seq[byte]] {.async: (raises: [CancelledError]).} = without mounted =? self.dispatch(key), error: return failure(error) @@ -131,7 +131,7 @@ method modifyGet*( method modify*( self: MountedDatastore, key: Key, - fn: Modify): Future[?!void] {.async: (raises: [CancelledError, AsyncLockError]).} = + fn: Modify): Future[?!void] {.async: (raises: [CancelledError]).} = without mounted =? self.dispatch(key), error: return failure(error) diff --git a/datastore/sql/sqliteds.nim b/datastore/sql/sqliteds.nim index ccd9e92..7e9c9bf 100644 --- a/datastore/sql/sqliteds.nim +++ b/datastore/sql/sqliteds.nim @@ -40,7 +40,7 @@ proc newRollbackError(rbErr: ref CatchableError, opErrMsg: string): ref Rollback proc newRollbackError(rbErr: ref CatchableError, opErr: ref CatchableError): ref RollbackError = return newRollbackError(rbErr, opErr) -method modifyGet*(self: SQLiteDatastore, key: Key, fn: ModifyGet): Future[?!seq[byte]] {.async: (raises: [CancelledError, AsyncLockError]).} = +method modifyGet*(self: SQLiteDatastore, key: Key, fn: ModifyGet): Future[?!seq[byte]] {.async: (raises: [CancelledError]).} = var retriesLeft = 100 # allows reasonable concurrency, avoids infinite loop aux: seq[byte] @@ -135,7 +135,7 @@ method modifyGet*(self: SQLiteDatastore, key: Key, fn: ModifyGet): Future[?!seq[ return success(aux) -method modify*(self: SQLiteDatastore, key: Key, fn: Modify): Future[?!void] {.async: (raises: [CancelledError, AsyncLockError]).} = +method modify*(self: SQLiteDatastore, key: Key, fn: Modify): Future[?!void] {.async: (raises: [CancelledError]).} = proc wrappedFn(maybeValue: ?seq[byte]): Future[(?seq[byte], seq[byte])] {.async.} = let res = await fn(maybeValue) let ignoredAux = newSeq[byte]() diff --git a/datastore/tieredds.nim b/datastore/tieredds.nim index 2118320..eaf62be 100644 --- a/datastore/tieredds.nim +++ b/datastore/tieredds.nim @@ -133,7 +133,7 @@ method put*( method modifyGet*( self: TieredDatastore, key: Key, - fn: ModifyGet): Future[?!seq[byte]] {.async: (raises: [CancelledError, AsyncLockError]).} = + fn: ModifyGet): Future[?!seq[byte]] {.async: (raises: [CancelledError]).} = let pending = await allFinished(self.stores.mapIt(it.modifyGet(key, fn))) @@ -154,7 +154,7 @@ method modifyGet*( method modify*( self: TieredDatastore, key: Key, - fn: Modify): Future[?!void] {.async: (raises: [CancelledError, AsyncLockError]).} = + fn: Modify): Future[?!void] {.async: (raises: [CancelledError]).} = let pending = await allFinished(self.stores.mapIt(it.modify(key, fn))) diff --git a/datastore/typedds.nim b/datastore/typedds.nim index 4bf76c2..982016e 100644 --- a/datastore/typedds.nim +++ b/datastore/typedds.nim @@ -102,7 +102,7 @@ proc get*[T](self: TypedDatastore, key: Key): Future[?!T] {.async: (raises: [Can return failure(error) return T.decode(bytes) -proc modify*[T](self: TypedDatastore, key: Key, fn: Modify[T]): Future[?!void] {.async: (raises: [CancelledError, AsyncLockError]).} = +proc modify*[T](self: TypedDatastore, key: Key, fn: Modify[T]): Future[?!void] {.async: (raises: [CancelledError]).} = requireDecoder(T) requireEncoder(T) @@ -123,7 +123,7 @@ proc modify*[T](self: TypedDatastore, key: Key, fn: Modify[T]): Future[?!void] { await self.ds.modify(key, wrappedFn) -proc modifyGet*[T, U](self: TypedDatastore, key: Key, fn: ModifyGet[T, U]): Future[?!U] {.async: (raises: [CancelledError, AsyncLockError]).} = +proc modifyGet*[T, U](self: TypedDatastore, key: Key, fn: ModifyGet[T, U]): Future[?!U] {.async: (raises: [CancelledError]).} = requireDecoder(T) requireEncoder(T) requireEncoder(U) From 92f9533c7d2e4ba1d19baac25f4059ebae29d6b9 Mon Sep 17 00:00:00 2001 From: Arnaud Date: Tue, 25 Feb 2025 13:43:49 +0100 Subject: [PATCH 4/7] Add more raises in async pragma --- datastore/fsds.nim | 11 ++++++++--- datastore/leveldb/leveldbds.nim | 4 ++-- datastore/query.nim | 6 +++--- datastore/sql/sqliteds.nim | 4 ++-- datastore/typedds.nim | 10 +++++----- 5 files changed, 20 insertions(+), 15 deletions(-) diff --git a/datastore/fsds.nim b/datastore/fsds.nim index a073b4c..c83a22a 100644 --- a/datastore/fsds.nim +++ b/datastore/fsds.nim @@ -189,7 +189,7 @@ method query*( var iter = QueryIter.new() - proc next(): Future[?!QueryResponse] {.async.} = + proc next(): Future[?!QueryResponse] {.async: (raises: [CancelledError]).} = let path = walker() @@ -208,8 +208,13 @@ method query*( key = Key.init(keyPath).expect("should not fail") data = if query.value: - self.readFile((basePath / path).absolutePath) - .expect("Should read file") + try: + self.readFile((basePath / path).absolutePath) + .expect("Should read file") + except ValueError as err: + return failure err + except OSError as err: + return failure err else: @[] diff --git a/datastore/leveldb/leveldbds.nim b/datastore/leveldb/leveldbds.nim index fc83764..3bf31fe 100644 --- a/datastore/leveldb/leveldbds.nim +++ b/datastore/leveldb/leveldbds.nim @@ -98,7 +98,7 @@ method query*( limit = query.limit ) - proc next(): Future[?!QueryResponse] {.async.} = + proc next(): Future[?!QueryResponse] {.async: (raises: [CancelledError]).} = if iter.finished: return failure(newException(QueryEndedError, "Calling next on a finished query!")) @@ -114,7 +114,7 @@ method query*( except LevelDbException as e: return failure("LevelDbDatastore.query -> next exception: " & $e.msg) - proc dispose(): Future[?!void] {.async.} = + proc dispose(): Future[?!void] {.async: (raises: [CancelledError]).} = dbIter.dispose() return success() diff --git a/datastore/query.nim b/datastore/query.nim index 94f1a83..ab1ef5f 100644 --- a/datastore/query.nim +++ b/datastore/query.nim @@ -23,8 +23,8 @@ type QueryResponse* = tuple[key: ?Key, data: seq[byte]] QueryEndedError* = object of DatastoreError - GetNext* = proc(): Future[?!QueryResponse] {.raises: [], gcsafe, closure.} - IterDispose* = proc(): Future[?!void] {.raises: [], gcsafe.} + GetNext* = proc(): Future[?!QueryResponse] {.async: (raises: [CancelledError]), gcsafe, closure.} + IterDispose* = proc(): Future[?!void] {.async: (raises: [CancelledError]), gcsafe.} QueryIter* = ref object finished*: bool next*: GetNext @@ -34,7 +34,7 @@ iterator items*(q: QueryIter): Future[?!QueryResponse] = while not q.finished: yield q.next() -proc defaultDispose(): Future[?!void] {.gcsafe, async.} = +proc defaultDispose(): Future[?!void] {.gcsafe, async: (raises: [CancelledError]).} = return success() proc new*(T: type QueryIter, dispose = defaultDispose): T = diff --git a/datastore/sql/sqliteds.nim b/datastore/sql/sqliteds.nim index 7e9c9bf..82a2442 100644 --- a/datastore/sql/sqliteds.nim +++ b/datastore/sql/sqliteds.nim @@ -267,7 +267,7 @@ method query*( if not (v == SQLITE_OK): return failure newException(DatastoreError, $sqlite3_errstr(v)) - proc next(): Future[?!QueryResponse] {.async.} = + proc next(): Future[?!QueryResponse] {.async: (raises: [CancelledError]).} = if iter.finished: return failure(newException(QueryEndedError, "Calling next on a finished query!")) @@ -321,7 +321,7 @@ method query*( iter.finished = true return failure newException(DatastoreError, $sqlite3_errstr(v)) - iter.dispose = proc(): Future[?!void] {.async.} = + iter.dispose = proc(): Future[?!void] {.async: (raises: [CancelledError]).} = discard sqlite3_reset(s) discard sqlite3_clear_bindings(s) iter.next = nil diff --git a/datastore/typedds.nim b/datastore/typedds.nim index 982016e..7c29da5 100644 --- a/datastore/typedds.nim +++ b/datastore/typedds.nim @@ -47,11 +47,11 @@ type TypedDatastore* = ref object of RootObj ds*: Datastore - Modify*[T] = proc(v: ?T): Future[?T] {.raises: [CatchableError], gcsafe, closure.} - ModifyGet*[T, U] = proc(v: ?T): Future[(?T, U)] {.raises: [CatchableError], gcsafe, closure.} + Modify*[T] = proc(v: ?T): Future[?T] {.raises: [CancelledError], gcsafe, closure.} + ModifyGet*[T, U] = proc(v: ?T): Future[(?T, U)] {.raises: [CancelledError], gcsafe, closure.} QueryResponse*[T] = tuple[key: ?Key, value: ?!T] - GetNext*[T] = proc(): Future[?!QueryResponse[T]] {.raises: [], gcsafe, closure.} + GetNext*[T] = proc(): Future[?!QueryResponse[T]] {.async: (raises: [CancelledError]), gcsafe, closure.} QueryIter*[T] = ref object finished*: bool next*: GetNext[T] @@ -161,14 +161,14 @@ proc query*[T](self: TypedDatastore, q: Query): Future[?!QueryIter[T]] {.async: return failure(childErr) var iter = QueryIter[T]() - iter.dispose = proc (): Future[?!void] {.async.} = + iter.dispose = proc (): Future[?!void] {.async: (raises: [CancelledError]).} = await dsIter.dispose() if dsIter.finished: iter.finished = true return success(iter) - proc getNext: Future[?!QueryResponse[T]] {.async.} = + proc getNext: Future[?!QueryResponse[T]] {.async: (raises: [CancelledError]).} = without pair =? await dsIter.next(), error: return failure(error) From d583647c5b0120d22af388761f6b2c952920116d Mon Sep 17 00:00:00 2001 From: Arnaud Date: Tue, 25 Feb 2025 13:52:37 +0100 Subject: [PATCH 5/7] Propagate CancelledError --- datastore/defaultimpl.nim | 2 ++ datastore/sql/sqliteds.nim | 2 ++ 2 files changed, 4 insertions(+) diff --git a/datastore/defaultimpl.nim b/datastore/defaultimpl.nim index 72cd4b3..6b40ecd 100644 --- a/datastore/defaultimpl.nim +++ b/datastore/defaultimpl.nim @@ -33,6 +33,8 @@ proc defaultModifyGetImpl*( try: (maybeNewData, aux) = await fn(maybeCurrentData) + except CancelledError as err: + raise err except CatchableError as err: return failure(err) diff --git a/datastore/sql/sqliteds.nim b/datastore/sql/sqliteds.nim index 82a2442..d6a42dd 100644 --- a/datastore/sql/sqliteds.nim +++ b/datastore/sql/sqliteds.nim @@ -62,6 +62,8 @@ method modifyGet*(self: SQLiteDatastore, key: Key, fn: ModifyGet): Future[?!seq[ try: (maybeNewData, aux) = await fn(maybeCurrentData) + except CancelledError as err: + raise err except CatchableError as err: return failure(err) From 950990720abf4e3d708edc1f2adf6440296fb13e Mon Sep 17 00:00:00 2001 From: Arnaud Date: Mon, 10 Mar 2025 14:52:50 +0100 Subject: [PATCH 6/7] Use await instead of fut.read --- datastore/tieredds.nim | 45 ++++++++++++------------------------------ 1 file changed, 13 insertions(+), 32 deletions(-) diff --git a/datastore/tieredds.nim b/datastore/tieredds.nim index eaf62be..cacc119 100644 --- a/datastore/tieredds.nim +++ b/datastore/tieredds.nim @@ -47,11 +47,8 @@ method delete*( pending = await allFinished(self.stores.mapIt(it.delete(key))) for fut in pending: - try: - if fut.read().isErr: - return fut.read() - except FuturePendingError as err: - return failure err + let res = await fut + if res.isErr: return res return success() @@ -64,11 +61,8 @@ method delete*( pending = await allFinished(self.stores.mapIt(it.delete(key))) for fut in pending: - try: - if fut.read().isErr: - return fut.read() - except FuturePendingError as err: - return failure err + let res = await fut + if res.isErr: return res return success() @@ -105,11 +99,8 @@ method put*( pending = await allFinished(self.stores.mapIt(it.put(key, data))) for fut in pending: - try: - if fut.read().isErr: - return fut.read() - except FuturePendingError as err: - return failure err + let res = await fut + if res.isErr: return res return success() @@ -122,11 +113,8 @@ method put*( pending = await allFinished(self.stores.mapIt(it.put(entry.key, entry.data))) for fut in pending: - try: - if fut.read().isErr: - return fut.read() - except FuturePendingError as err: - return failure err + let res = await fut + if res.isErr: return res return success() @@ -141,13 +129,9 @@ method modifyGet*( var aux = newSeq[byte]() for fut in pending: - try: - if fut.read().isErr: - return fut.read() - else: - aux.add(fut.read().get) - except FuturePendingError as err: - return failure err + let res = await fut + if res.isErr: return res + aux.add(res.get) return success(aux) @@ -160,11 +144,8 @@ method modify*( pending = await allFinished(self.stores.mapIt(it.modify(key, fn))) for fut in pending: - try: - if fut.read().isErr: - return fut.read() - except FuturePendingError as err: - return failure err + let res = await fut + if res.isErr: return res return success() From a7ee4b170ab7efd1fa921aab97896886f9a3e8a7 Mon Sep 17 00:00:00 2001 From: Arnaud Date: Tue, 11 Mar 2025 09:12:34 +0100 Subject: [PATCH 7/7] Use short syntax with nim-results --- datastore/tieredds.nim | 20 +++++++------------- 1 file changed, 7 insertions(+), 13 deletions(-) diff --git a/datastore/tieredds.nim b/datastore/tieredds.nim index cacc119..c86774f 100644 --- a/datastore/tieredds.nim +++ b/datastore/tieredds.nim @@ -47,8 +47,7 @@ method delete*( pending = await allFinished(self.stores.mapIt(it.delete(key))) for fut in pending: - let res = await fut - if res.isErr: return res + ? await fut return success() @@ -61,8 +60,7 @@ method delete*( pending = await allFinished(self.stores.mapIt(it.delete(key))) for fut in pending: - let res = await fut - if res.isErr: return res + ? await fut return success() @@ -99,8 +97,7 @@ method put*( pending = await allFinished(self.stores.mapIt(it.put(key, data))) for fut in pending: - let res = await fut - if res.isErr: return res + ? await fut return success() @@ -113,8 +110,7 @@ method put*( pending = await allFinished(self.stores.mapIt(it.put(entry.key, entry.data))) for fut in pending: - let res = await fut - if res.isErr: return res + ? await fut return success() @@ -129,9 +125,8 @@ method modifyGet*( var aux = newSeq[byte]() for fut in pending: - let res = await fut - if res.isErr: return res - aux.add(res.get) + let res = ? await fut + aux.add(res) return success(aux) @@ -144,8 +139,7 @@ method modify*( pending = await allFinished(self.stores.mapIt(it.modify(key, fn))) for fut in pending: - let res = await fut - if res.isErr: return res + ? await fut return success()