Skip to content

Commit 66a523a

Browse files
committed
feat: Improves transaction suport on a per-driver level
1 parent 07a5c60 commit 66a523a

File tree

10 files changed

+236
-172
lines changed

10 files changed

+236
-172
lines changed

CONTRIBUTING.md

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,10 +40,19 @@ Written in AVA. Please see /test/\*.spec.ts for examples. When writing driver te
4040

4141
- By default, only the Loki driver tests will run. This is because not every architecture can run every DB
4242
- Setting `process.env.MONGO_URI` will enable MongoDB tests using an external MongoDB instance. Please ensure it supports Replica Sets
43-
- Setting `process.env.POSTGRES_URI` will enable Postgres tests using an external Postgres instance
43+
- Setting `process.env.POSTGRES_URL` will enable Postgres tests using an external Postgres instance
4444

4545
Until [this ava issue](https://github.com/avajs/ava/issues/2979) is resolved, we work around this by selecting `test`/`test.skip` as a runtime evaluation.
4646

47+
#### 🐋🌿 Docker + Mongo
48+
49+
These tests work with the docker image for mongodb, with the following caveats:
50+
51+
1. After pulling, you must log into the instance and run `rs.initiate()` to enable the replica set
52+
2. You can then connect via Direct Connection with a URI such as `mongodb://127.0.0.1:27017/?replicaSet=rs0&directConnection=true`
53+
54+
You may also use a free Atlas instance from MongoDB to test this driver, as all Atlas instances run replica sets by default.
55+
4756
### 🏁 E2E Testing
4857

4958
End to End tests are accepted. Please use the `LokiAdapter` for any tests, as it does not mandate the external dependencies to be loaded.

src/driver/base.ts

Lines changed: 25 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,8 @@ const asynced = (...args: unknown[]) =>
1616
r(args);
1717
});
1818

19-
export class BaseDriver<Schema = unknown, Table = unknown>
20-
implements Driver<Schema, Table>
19+
export class BaseDriver<Schema = unknown, Table = unknown, TxInfo = unknown>
20+
implements Driver<Schema, Table, TxInfo>
2121
{
2222
events: DriverEmitter;
2323
private conn: unknown;
@@ -67,74 +67,74 @@ export class BaseDriver<Schema = unknown, Table = unknown>
6767
}
6868

6969
/** Bookend a transaction with driver specific handling */
70-
async transaction(body: () => Promise<unknown>) {
70+
async transaction(body: (txn: TxInfo) => Promise<unknown>) {
7171
await asynced(body);
7272
throw new DriverNotImplementedError();
7373
}
7474

7575
/** Take N items from the queue for processing */
76-
async take(visibility: number, limit = 1): Promise<QueueDoc[]> {
77-
await asynced(visibility, limit);
76+
async take(visibility: number, limit = 1, tx?: TxInfo): Promise<QueueDoc[]> {
77+
await asynced(visibility, limit, tx);
7878
throw new DriverNotImplementedError();
7979
}
8080

8181
/** Ack a job, removing it from the queue */
82-
async ack(ack: string) {
83-
await asynced(ack);
82+
async ack(ack: string, tx?: TxInfo) {
83+
await asynced(ack, tx);
8484
throw new DriverNotImplementedError();
8585
}
8686

8787
/** Promote a job, making it immediately available for running */
88-
async promote(ref: string) {
89-
await asynced(ref);
88+
async promote(ref: string, tx?: TxInfo) {
89+
await asynced(ref, tx);
9090
throw new DriverNotImplementedError();
9191
}
9292

9393
/** Delay a job, pushing its visibility window out */
94-
async delay(ref: string, delayBy: number) {
95-
await asynced(ref, delayBy);
94+
async delay(ref: string, delayBy: number, tx?: TxInfo) {
95+
await asynced(ref, delayBy, tx);
9696
throw new DriverNotImplementedError();
9797
}
9898

9999
/** Replay a job, copying and inserting a new job to run immediately */
100-
async replay(ref: string) {
101-
await asynced(ref);
100+
async replay(ref: string, tx?: TxInfo) {
101+
await asynced(ref, tx);
102102
throw new DriverNotImplementedError();
103103
}
104104

105105
/** Fail a job, shifting the next run ahead to a retry time */
106-
async fail(ack: string, retryIn: number, attempt: number) {
107-
await asynced(ack, retryIn, attempt);
106+
async fail(ack: string, retryIn: number, attempt: number, tx?: TxInfo) {
107+
await asynced(ack, retryIn, attempt, tx);
108108
throw new DriverNotImplementedError();
109109
}
110110

111111
/** Place an item into the dead letter queue and ack it */
112-
async dead(doc: QueueDoc) {
113-
await asynced(doc);
112+
async dead(doc: QueueDoc, tx?: TxInfo) {
113+
await asynced(doc, tx);
114114
throw new DriverNotImplementedError();
115115
}
116116

117117
/** Extend the runtime of a job */
118-
async ping(ack: string, extendBy = 15) {
119-
await asynced(ack, extendBy);
118+
async ping(ack: string, extendBy = 15, tx?: TxInfo) {
119+
await asynced(ack, extendBy, tx);
120120
throw new DriverNotImplementedError();
121121
}
122122

123123
/** Remove any jobs that are before a certain date */
124-
async clean(before: Date) {
125-
await asynced(before);
124+
async clean(before: Date, tx?: TxInfo) {
125+
await asynced(before, tx);
126126
throw new DriverNotImplementedError();
127127
}
128128

129129
/** Replace any upcoming instances of a doc with new data */
130-
async replaceUpcoming(doc: QueueDoc): Promise<QueueDoc> {
131-
await asynced(doc);
130+
async replaceUpcoming(doc: QueueDoc, tx?: TxInfo): Promise<QueueDoc> {
131+
await asynced(doc, tx);
132132
throw new DriverNotImplementedError();
133133
}
134134

135135
/** Remove all upcoming instances of a job by its ref */
136-
async removeUpcoming(ref: string) {
137-
await asynced(ref);
136+
async removeUpcoming(ref: string, tx?: TxInfo) {
137+
await asynced(ref, tx);
138138
throw new DriverNotImplementedError();
139139
}
140140

src/driver/loki.ts

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,11 @@ export const getClient = (identifier: string) => {
102102
* LokiJS Driver Class. Creates a connection that allows DocMQ to talk to
103103
* an in-memory LokiJS instance
104104
*/
105-
export class LokiDriver extends BaseDriver<Loki, Collection<LokiDoc>> {
105+
export class LokiDriver extends BaseDriver<
106+
Loki,
107+
Collection<LokiDoc>,
108+
undefined
109+
> {
106110
protected _db: Loki | undefined;
107111
protected _jobs: Collection<LokiDoc> | undefined;
108112

@@ -159,15 +163,15 @@ export class LokiDriver extends BaseDriver<Loki, Collection<LokiDoc>> {
159163
});
160164
}
161165

162-
async transaction(body: () => Promise<unknown>): Promise<void> {
166+
async transaction(body: (tx: undefined) => Promise<unknown>): Promise<void> {
163167
await this.ready();
164168

165169
if (!this._jobs) {
166170
throw new DriverInitializationError();
167171
}
168172

169173
this._jobs.startTransaction();
170-
await body();
174+
await body(undefined);
171175
this._jobs.commit();
172176
}
173177

0 commit comments

Comments
 (0)