Skip to content

Commit

Permalink
Merge pull request #129 from hayd/alternative-123
Browse files Browse the repository at this point in the history
Use a per Connection query lock
  • Loading branch information
hayd authored May 24, 2020
2 parents a712453 + ad76bce commit efdf58b
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 3 deletions.
17 changes: 14 additions & 3 deletions connection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ import { PacketReader } from "./packet_reader.ts";
import { QueryConfig, QueryResult, Query } from "./query.ts";
import { parseError } from "./error.ts";
import { ConnectionParams } from "./connection_params.ts";
import { DeferredStack } from "./deferred.ts";

export enum Format {
TEXT = 0,
Expand Down Expand Up @@ -86,6 +87,10 @@ export class Connection {
private _pid?: number;
private _secretKey?: number;
private _parameters: { [key: string]: string } = {};
private _queryLock: DeferredStack<undefined> = new DeferredStack(
1,
[undefined],
);

constructor(private connParams: ConnectionParams) {}

Expand Down Expand Up @@ -528,10 +533,16 @@ export class Connection {
}

async query(query: Query): Promise<QueryResult> {
if (query.args.length === 0) {
return await this._simpleQuery(query);
await this._queryLock.pop();
try {
if (query.args.length === 0) {
return await this._simpleQuery(query);
} else {
return await this._preparedQuery(query);
}
} finally {
this._queryLock.push(undefined);
}
return await this._preparedQuery(query);
}

private _processRowDescription(msg: Message): RowDescription {
Expand Down
18 changes: 18 additions & 0 deletions tests/queries.ts
Original file line number Diff line number Diff line change
Expand Up @@ -191,3 +191,21 @@ testClient(async function resultMetadata() {
"CREATE UNLOGGED TABLE ids (id integer)",
"INSERT INTO ids VALUES (100), (200), (300), (400), (500), (600)",
]);

testClient(async function transactionWithConcurrentQueries() {
const result = await CLIENT.query("BEGIN");

assertEquals(result.rows.length, 0);
const concurrentCount = 5;
const queries = [...Array(concurrentCount)].map((_, i) => {
return CLIENT.query({
text: "INSERT INTO ids (id) VALUES ($1) RETURNING id;",
args: [i],
});
});
const results = await Promise.all(queries);

results.forEach((r, i) => {
assertEquals(r.rows[0][0], i);
});
});

0 comments on commit efdf58b

Please # to comment.