Skip to content

Commit

Permalink
[MS] Watch entries with bindings
Browse files Browse the repository at this point in the history
  • Loading branch information
Max-7 committed Jun 17, 2024
1 parent 8a56ee2 commit b84b503
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 17 deletions.
10 changes: 9 additions & 1 deletion client/src/parsec/file.ts
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,15 @@ export async function statFolderChildren(
path: FsPath,
): Promise<Result<Array<EntryStat>, WorkspaceStatFolderChildrenError>> {
if (!needsMocks()) {
const result = await libparsec.workspaceStatFolderChildren(workspaceHandle, path);
const watchResult = await libparsec.workspaceWatchEntryOneshot(workspaceHandle, path);

let result;
if (!watchResult.ok) {
result = await libparsec.workspaceStatFolderChildren(workspaceHandle, path);
} else {
result = await libparsec.workspaceStatFolderChildrenById(workspaceHandle, watchResult.value);
}

if (!result.ok) {
return result;
}
Expand Down
18 changes: 6 additions & 12 deletions client/src/parsec/login.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,6 @@ import { DateTime } from 'luxon';
export interface LoggedInDeviceInfo {
handle: ConnectionHandle;
device: AvailableDevice;
// Used to simulate update events, remove when we have real events
intervalId: any;
}

const loggedInDevices: Array<LoggedInDeviceInfo> = [];
Expand Down Expand Up @@ -159,6 +157,9 @@ export async function login(
case ClientEventTag.WorkspacesSelfAccessChanged:
eventDistributor.dispatchEvent(Events.WorkspaceUpdated);
break;
case ClientEventTag.WorkspaceWatchedEntryChanged:
eventDistributor.dispatchEvent(Events.EntryUpdated, undefined, 300);
break;
default:
window.electronAPI.log('debug', `Unhandled event ${event.tag}`);
break;
Expand All @@ -177,19 +178,15 @@ export async function login(
const clientConfig = getClientConfig();
const result = await libparsec.clientStart(clientConfig, callback, accessStrategy);
if (result.ok) {
// Simulate an update event every 10s to force a refresh
const intervalId = setInterval(() => {
eventDistributor.dispatchEvent(Events.EntryUpdated);
}, 10000);
loggedInDevices.push({ handle: result.value, device: device, intervalId: intervalId });
loggedInDevices.push({ handle: result.value, device: device });
}
return result;
} else {
if (
accessStrategy.tag === DeviceAccessStrategyTag.Password &&
['P@ssw0rd.', 'AVeryL0ngP@ssw0rd'].includes((accessStrategy as DeviceAccessStrategyPassword).password)
) {
loggedInDevices.push({ handle: DEFAULT_HANDLE, device: device, intervalId: null });
loggedInDevices.push({ handle: DEFAULT_HANDLE, device: device });
return { ok: true, value: DEFAULT_HANDLE };
}
return {
Expand All @@ -212,10 +209,7 @@ export async function logout(handle?: ConnectionHandle | undefined | null): Prom
if (result.ok) {
const index = loggedInDevices.findIndex((info) => info.handle === handle);
if (index !== -1) {
const removed = loggedInDevices.splice(index, 1);
if (removed && removed.length > 0) {
clearInterval(removed[0].intervalId);
}
loggedInDevices.splice(index, 1);
}
}
return result;
Expand Down
38 changes: 34 additions & 4 deletions client/src/services/eventDistributor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,17 +43,47 @@ interface Callback {

class EventDistributor {
private callbacks: Array<Callback>;
private timeouts: Map<Events, number>;

constructor() {
this.callbacks = [];
this.timeouts = new Map<number, Events>();
}

async dispatchEvent(event: Events, data?: EventData): Promise<void> {
for (const cb of this.callbacks) {
if (event & cb.events) {
await cb.funct(event, data);
async dispatchEvent(event: Events, data?: EventData, aggregateTime?: number): Promise<void> {
async function sendToAll(callbacks: Array<Callback>, event: Events, data?: EventData): Promise<void> {
for (const cb of callbacks) {
if (event & cb.events) {
await cb.funct(event, data);
}
}
}

// In some cases, events can occur very close to each other, leading to some heavy operations.
// We can aggregate those cases in order to distribute only one event if multiple occur in a short
// time lapse.
if (aggregateTime !== undefined) {
if (data) {
// Can't have data with an aggregateTime, we wouldn't know what data to use
console.warn('Cannot have an aggregate time with data, ignoring this event.');
return;
}
// Clear previous interval if any
if (this.timeouts.has(event)) {
const interval = this.timeouts.get(event);
this.timeouts.delete(event);
window.clearInterval(interval);
}
// Create a new timeout
const interval = window.setTimeout(async () => {
await sendToAll(this.callbacks, event, undefined);
}, aggregateTime);
// Add it to the list
this.timeouts.set(event, interval);
}

Check failure on line 83 in client/src/services/eventDistributor.ts

View workflow job for this annotation

GitHub Actions / web / 🌐 Web tests

Closing curly brace does not appear on the same line as the subsequent block
else {
await sendToAll(this.callbacks, event, data);
}
}

async registerCallback(events: number, funct: (event: Events, data?: EventData) => Promise<void>): Promise<string> {
Expand Down

0 comments on commit b84b503

Please sign in to comment.