Skip to content

Commit

Permalink
debounce
Browse files Browse the repository at this point in the history
  • Loading branch information
ponderingdemocritus committed Dec 19, 2024
1 parent ebf790a commit 2adc56d
Show file tree
Hide file tree
Showing 4 changed files with 131 additions and 13 deletions.
114 changes: 114 additions & 0 deletions client/src/dojo/debouncedQueries.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
import { Component, Metadata, Schema } from "@dojoengine/recs";
import { ToriiClient } from "@dojoengine/torii-client";
import debounce from "lodash/debounce";
import {
addMarketSubscription,
addToSubscription,
addToSubscriptionOneKeyModelbyRealmEntityId,
addToSubscriptionTwoKeyModelbyRealmEntityId,
syncPosition,
} from "./queries";

// Queue class to manage requests
class RequestQueue {
private queue: Array<() => Promise<void>> = [];
private processing = false;
private batchSize = 3; // Number of concurrent requests
private batchDelayMs = 100; // Delay between batches

async add(request: () => Promise<void>) {
this.queue.push(request);
if (!this.processing) {
this.processing = true;
this.processQueue();
}
}

private async processQueue() {
while (this.queue.length > 0) {
const batch = this.queue.splice(0, this.batchSize);

try {
await Promise.all(batch.map((request) => request()));
} catch (error) {
console.error("Error processing request batch:", error);
}

if (this.queue.length > 0) {
// Add delay between batches to prevent overwhelming the server
await new Promise((resolve) => setTimeout(resolve, this.batchDelayMs));
}
}
this.processing = false;
}

clear() {
this.queue = [];
}
}

// Create separate queues for different types of requests
const positionQueue = new RequestQueue();
const subscriptionQueue = new RequestQueue();
const marketQueue = new RequestQueue();

// Debounced functions that add to queues
export const debouncedSyncPosition = debounce(
async <S extends Schema>(client: ToriiClient, components: Component<S, Metadata, undefined>[], entityID: string) => {
await positionQueue.add(() => syncPosition(client, components, entityID));
},
100,
{ leading: true }, // Add leading: true to execute immediately on first call
);

export const debouncedAddToSubscriptionTwoKey = debounce(
async <S extends Schema>(
client: ToriiClient,
components: Component<S, Metadata, undefined>[],
entityID: string[],
) => {
await subscriptionQueue.add(() => addToSubscriptionTwoKeyModelbyRealmEntityId(client, components, entityID));
},
250,
{ leading: true },
);

export const debouncedAddToSubscriptionOneKey = debounce(
async <S extends Schema>(
client: ToriiClient,
components: Component<S, Metadata, undefined>[],
entityID: string[],
) => {
await subscriptionQueue.add(() => addToSubscriptionOneKeyModelbyRealmEntityId(client, components, entityID));
},
250,
{ leading: true },
);

export const debouncedAddToSubscription = debounce(
async <S extends Schema>(
client: ToriiClient,
components: Component<S, Metadata, undefined>[],
entityID: string[],
position?: { x: number; y: number }[],
) => {
await subscriptionQueue.add(() => addToSubscription(client, components, entityID, position));
},
250,
{ leading: true },
);

export const debouncedAddMarketSubscription = debounce(
async <S extends Schema>(client: ToriiClient, components: Component<S, Metadata, undefined>[]) => {
await marketQueue.add(() => addMarketSubscription(client, components));
},
500,
{ leading: true },
);

// Utility function to clear all queues if needed
export const clearAllQueues = () => {
positionQueue.clear();
subscriptionQueue.clear();
marketQueue.clear();
};
10 changes: 5 additions & 5 deletions client/src/dojo/queries.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ export const syncPosition = async <S extends Schema>(
components,
[],
[],
30_000,
5_000,
);
};

Expand Down Expand Up @@ -53,7 +53,7 @@ export const addToSubscriptionTwoKeyModelbyRealmEntityId = async <S extends Sche
components,
[],
[],
30_000,
5_000,
);
};

Expand Down Expand Up @@ -81,7 +81,7 @@ export const addToSubscriptionOneKeyModelbyRealmEntityId = async <S extends Sche
components,
[],
[],
30_000,
5_000,
);
};

Expand Down Expand Up @@ -122,7 +122,7 @@ export const addToSubscription = async <S extends Schema>(
components as any,
[],
[],
30_000,
5_000,
);
const end = performance.now();
console.log("AddToSubscriptionEnd", end - start);
Expand All @@ -145,7 +145,7 @@ export const addMarketSubscription = async <S extends Schema>(
components,
[],
[],
30_000,
5_000,
false,
);
const end = performance.now();
Expand Down
4 changes: 2 additions & 2 deletions client/src/ui/components/resources/InventoryResources.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { addToSubscription } from "@/dojo/queries";
import { debouncedAddToSubscription } from "@/dojo/debouncedQueries";
import { useDojo } from "@/hooks/context/DojoContext";
import { useResourceBalance, useResourcesUtils } from "@/hooks/helpers/useResources";
import { ResourceCost } from "@/ui/elements/ResourceCost";
Expand Down Expand Up @@ -52,7 +52,7 @@ export const InventoryResources = ({
setIsSyncing(true);
try {
console.log("AddToSubscriptionStart - 4");
await addToSubscription(dojo.network.toriiClient, dojo.network.contractComponents as any, [
await debouncedAddToSubscription(dojo.network.toriiClient, dojo.network.contractComponents as any, [
entityId.toString(),
]);
localStorage.setItem(cacheKey, now.toString());
Expand Down
16 changes: 10 additions & 6 deletions client/src/ui/layouts/World.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,11 @@ import { lazy, Suspense, useEffect, useMemo, useState } from "react";
import { Redirect } from "wouter";
import useUIStore from "../../hooks/store/useUIStore";

import { addMarketSubscription, addToSubscription, addToSubscriptionOneKeyModelbyRealmEntityId } from "@/dojo/queries";
import {
debouncedAddMarketSubscription,
debouncedAddToSubscription,
debouncedAddToSubscriptionOneKey,
} from "@/dojo/debouncedQueries";
import { useDojo } from "@/hooks/context/DojoContext";
import { PlayerStructure, useEntities } from "@/hooks/helpers/useEntities";
import { useStructureEntityId } from "@/hooks/helpers/useStructureEntityId";
Expand Down Expand Up @@ -143,7 +147,7 @@ export const World = ({ backgroundImage }: { backgroundImage: string }) => {
console.log("AddToSubscriptionStart - 1");
try {
await Promise.all([
addToSubscription(
debouncedAddToSubscription(
dojo.network.toriiClient,
dojo.network.contractComponents as any,
[structureEntityId.toString()],
Expand All @@ -164,13 +168,13 @@ export const World = ({ backgroundImage }: { backgroundImage: string }) => {
try {
setWorldLoading(true);
console.log("AddToSubscriptionStart - 2");
addToSubscription(
debouncedAddToSubscription(
dojo.network.toriiClient,
dojo.network.contractComponents as any,
[...filteredStructures.map((structure) => structure.entity_id.toString())],
[...filteredStructures.map((structure) => ({ x: structure.position.x, y: structure.position.y }))],
);
addToSubscriptionOneKeyModelbyRealmEntityId(dojo.network.toriiClient, dojo.network.contractComponents as any, [
debouncedAddToSubscriptionOneKey(dojo.network.toriiClient, dojo.network.contractComponents as any, [
...filteredStructures.map((structure) => structure.entity_id.toString()),
]);
} catch (error) {
Expand All @@ -184,10 +188,10 @@ export const World = ({ backgroundImage }: { backgroundImage: string }) => {
try {
setMarketLoading(true);
console.log("AddToSubscriptionStart - 3");
addToSubscription(dojo.network.toriiClient, dojo.network.contractComponents as any, [
debouncedAddToSubscription(dojo.network.toriiClient, dojo.network.contractComponents as any, [
ADMIN_BANK_ENTITY_ID.toString(),
]);
addMarketSubscription(dojo.network.toriiClient, dojo.network.contractComponents as any);
debouncedAddMarketSubscription(dojo.network.toriiClient, dojo.network.contractComponents as any);
} catch (error) {
console.error("Fetch failed", error);
} finally {
Expand Down

0 comments on commit 2adc56d

Please sign in to comment.