Skip to content

Commit

Permalink
add global sync locks
Browse files Browse the repository at this point in the history
  • Loading branch information
stevensJourney committed Jan 31, 2024
1 parent c6138f5 commit 787668a
Show file tree
Hide file tree
Showing 8 changed files with 65 additions and 8 deletions.
5 changes: 5 additions & 0 deletions .changeset/chilled-poets-think.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@journeyapps/powersync-sdk-react-native': patch
---

Added global locks for syncing connections. Added warning when creating multiple Powersync instances.
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import Logger from 'js-logger';
import { DBAdapter } from '../db/DBAdapter';
import { Schema } from '../db/schema/Schema';
import { AbstractPowerSyncDatabase, PowerSyncDatabaseOptions } from './AbstractPowerSyncDatabase';
Expand All @@ -15,7 +16,9 @@ export interface PowerSyncOpenFactoryOptions extends Partial<PowerSyncDatabaseOp
}

export abstract class AbstractPowerSyncDatabaseOpenFactory {
constructor(protected options: PowerSyncOpenFactoryOptions) {}
constructor(protected options: PowerSyncOpenFactoryOptions) {
options.logger = options.logger ?? Logger.get(`PowerSync ${this.options.dbFilename}`);
}

get schema() {
return this.options.schema;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,16 @@ export interface LockOptions<T> {

export interface AbstractStreamingSyncImplementationOptions {
adapter: BucketStorageAdapter;
remote: AbstractRemote;
uploadCrud: () => Promise<void>;
crudUploadThrottleMs?: number;
/**
* An identifier for which PowerSync DB this sync implementation is
* linked to. Most commonly DB name, but not restricted to DB name.
*/
identifier?: string;
logger?: ILogger;
remote: AbstractRemote;
retryDelayMs?: number;
crudUploadThrottleMs?: number;
}

export interface StreamingSyncImplementationListener extends BaseListener {
Expand Down
4 changes: 2 additions & 2 deletions packages/powersync-sdk-react-native/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
},
"homepage": "https://docs.powersync.co/",
"peerDependencies": {
"@journeyapps/react-native-quick-sqlite": "0.0.0-dev-20240131124845",
"@journeyapps/react-native-quick-sqlite": "^1.1.1",
"base-64": "^1.0.0",
"react": "*",
"react-native": "*",
Expand All @@ -44,7 +44,7 @@
"async-lock": "^1.4.0"
},
"devDependencies": {
"@journeyapps/react-native-quick-sqlite": "0.0.0-dev-20240131124845",
"@journeyapps/react-native-quick-sqlite": "^1.1.1",
"@types/async-lock": "^1.4.0",
"react-native": "0.72.4",
"react": "18.2.0",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@ export class PowerSyncDatabase extends AbstractPowerSyncDatabase {
await connector.uploadData(this);
},
retryDelayMs: this.options.retryDelay,
crudUploadThrottleMs: this.options.crudUploadThrottleMs
crudUploadThrottleMs: this.options.crudUploadThrottleMs,
identifier: this.options.database.name
});
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,19 @@ import {
AbstractPowerSyncDatabase,
AbstractPowerSyncDatabaseOpenFactory,
DBAdapter,
PowerSyncDatabaseOptions
PowerSyncDatabaseOptions,
PowerSyncOpenFactoryOptions
} from '@journeyapps/powersync-sdk-common';
import { PowerSyncDatabase } from '../../../db/PowerSyncDatabase';
import { RNQSDBAdapter } from './RNQSDBAdapter';

export class RNQSPowerSyncDatabaseOpenFactory extends AbstractPowerSyncDatabaseOpenFactory {
protected instanceGenerated: boolean;

constructor(options: PowerSyncOpenFactoryOptions) {
super(options);
this.instanceGenerated = false;
}
protected openDB(): DBAdapter {
/**
* React Native Quick SQLite opens files relative to the `Documents`dir on iOS and the `Files`
Expand Down Expand Up @@ -38,6 +45,10 @@ export class RNQSPowerSyncDatabaseOpenFactory extends AbstractPowerSyncDatabaseO
}

generateInstance(options: PowerSyncDatabaseOptions): AbstractPowerSyncDatabase {
if (this.instanceGenerated) {
this.options.logger?.warn('Generating multiple PowerSync instances can sometimes cause unexpected results.');
}
this.instanceGenerated = true;
return new PowerSyncDatabase(options);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,38 @@ import {
LockType
} from '@journeyapps/powersync-sdk-common';
import Lock from 'async-lock';

/**
* Global locks which prevent multiple instances from syncing
* concurrently.
*/
const LOCKS = new Map<string, Map<LockType, Lock>>();

export class ReactNativeStreamingSyncImplementation extends AbstractStreamingSyncImplementation {
locks: Map<LockType, Lock>;

constructor(options: AbstractStreamingSyncImplementationOptions) {
super(options);
this.locks = new Map();
this.initLocks();
}

/**
* Configures global locks on sync process
*/
initLocks() {
const { identifier } = this.options;
if (identifier && LOCKS.has(identifier)) {
this.locks = LOCKS.get(identifier);
return;
}

this.locks = new Map<LockType, Lock>();
this.locks.set(LockType.CRUD, new Lock());
this.locks.set(LockType.SYNC, new Lock());

if (identifier) {
LOCKS.set(identifier, this.locks);
}
}

obtainLock<T>(lockOptions: LockOptions<T>): Promise<T> {
Expand Down
8 changes: 8 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -2228,6 +2228,14 @@
lodash "^4.17.21"
uuid "3.4.0"

"@journeyapps/react-native-quick-sqlite@^1.1.1":
version "1.1.1"
resolved "https://registry.npmjs.org/@journeyapps/react-native-quick-sqlite/-/react-native-quick-sqlite-1.1.1.tgz#2b13d739ca73026453717c887246f8e4a23f5f44"
integrity sha512-5I8zUZoFRgtnagjQygqnSyWG0L39ycFvum+ytsMmFW8LY1GpEZ+a3I6fWggwM82/Cc9YOheCVRIz47g0uBBZug==
dependencies:
lodash "^4.17.21"
uuid "3.4.0"

"@jridgewell/gen-mapping@^0.3.0", "@jridgewell/gen-mapping@^0.3.2":
version "0.3.3"
resolved "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz#7e02e6eb5df901aaedb08514203b096614024098"
Expand Down

0 comments on commit 787668a

Please sign in to comment.