@omar#4289 same as, I am getting the

@omar same as, I am getting the same issue, I have explained my issue
No description
26 Replies
Harshil Bodara
Harshil BodaraOP13mo ago
the first time, it is working correctly, when re-call the water Schedule a second time does the calling schedule 2 times every 2 seconds, same as the next
omar4289
omar428913mo ago
What is the code in the worker ? Do you always refer to the same do instance ? @Harshil Bodara
Harshil Bodara
Harshil BodaraOP13mo ago
But whenever I call the schedule, I want to call the alarm only once export class Water { id: string | DurableObjectId; storage: DurableObjectStorage; doEverySeconds: number; env: Env;
constructor(state: DurableObjectState, env: Env) { this.storage = state.storage; this.id = state.id; this.doEverySeconds = 2; this.env = env; }
async fetch() { const alarmTime = await this.storage.get("alarmTime"); console.log("alarmTime",alarmTime) if (!alarmTime) { await this.scheduleAlarm(); } else { return new Response("Water alarm is already scheduled."); } return new Response("Water schedule Successfully!"); }
async alarm() { console.log("Water Alarm Doing"); await this.scheduleAlarm(); }
async scheduleAlarm() { let scheduledTime: number = Date.now() + this.doEverySeconds * 1000; await this.storage.put("alarmTime", scheduledTime.toString()); this.storage.setAlarm(scheduledTime); } }
Harshil Bodara
Harshil BodaraOP13mo ago
No description
omar4289
omar428913mo ago
Ah Ok, I get your point, basically what you want to do is execute your alarm call once in 2 seconds, regardless of how many requests you receive within the 2 seconds range, right ?
Harshil Bodara
Harshil BodaraOP13mo ago
yes, exactly
omar4289
omar428913mo ago
ok, let me send you the code
Harshil Bodara
Harshil BodaraOP13mo ago
for exmaple alaram calling First time call = schudle call every 2 second (working fine) second time call = 2 time schudle call every 2 second third time call = 3 time schudle call every 2 second but i want to do ------------------------------------- First time call = schudle call every 2 second (working fine) second time call = 1 time schudle call every 2 second third time call = 1 time schudle call every 2 second
Harshil Bodara
Harshil BodaraOP13mo ago
No description
omar4289
omar428913mo ago
export class Water { id: string | DurableObjectId; storage: DurableObjectStorage; doEverySeconds: number; env: Env;
constructor(state: DurableObjectState, env: Env) { this.storage = state.storage; this.id = state.id; this.doEverySeconds = 2; this.env = env; }
async fetch() { const alarmTime = await this.storage.get("alarmTime"); console.log("alarmTime",alarmTime) if (!alarmTime) { await this.scheduleAlarm(); } else { return new Response("Water alarm is already scheduled."); } return new Response("Water schedule Successfully!"); }
async alarm() { console.log("Water Alarm Doing"); await this.storage.delete("alarmTime"); }
async scheduleAlarm() { let scheduledTime: number = Date.now() + this.doEverySeconds * 1000; await this.storage.put("alarmTime", scheduledTime.toString()); this.storage.setAlarm(scheduledTime); } } Just replaced the this.scheduleAlarm in the alarm function to await storage.delete
Harshil Bodara
Harshil BodaraOP13mo ago
when i call the API, so alaram calling is only one time
No description
Harshil Bodara
Harshil BodaraOP13mo ago
not every 2 secondse
omar4289
omar428913mo ago
This will be the outcome: Call to DO at t + 1s: Will schedule the alarm Call to DO at t + 1.5s: Will return alarm already scheduled (therefore would do nothing) Call to DO at t + 2s: WIll return alarm already scheduled (therefore would do nothing) At t + 3s: The alarm will be executed At t + 5s: Nothing will happen, until the DO schedules the alarm again through the fetch Is this what you are trying to build ? Based on what I have provided, do you want the alarm to be executed still at t + 5s, t + 7s, .... t + 99s ?
Harshil Bodara
Harshil BodaraOP13mo ago
yes, like this
omar4289
omar428913mo ago
Can you send the code where you call your DO from the worker ? When you get the id and then send the fetch request to the DO
Harshil Bodara
Harshil BodaraOP13mo ago
but I want to when re-calling the schedule so before, schedule is clear(restart) and then the alarm calling
omar4289
omar428913mo ago
Ok, can you express it in a timeline like I did here From t + 1s, to t + 9s
Harshil Bodara
Harshil BodaraOP13mo ago
main.ts -------------------------- import { ThrowableRouter } from 'itty-router-extras'; import { Env } from '../types'; import { withDurables } from 'itty-durable'; export { Water } from './crons/water'; const router = ThrowableRouter(); router.all("", withDurables()); router.get('/water', async (request: Request, env: Env) => { const doId = env.WATER.newUniqueId(); const WaterInstance = env.WATER.get(doId); return WaterInstance.fetch(request, env); }); router.all("", ()=> { return new Response("Route not Found!") }); export default { fetch: router.handle, }; crons/water/index.ts --------------------------------- export class Water { id: string | DurableObjectId; storage: DurableObjectStorage; doEverySeconds: number; env: Env; constructor(state: DurableObjectState, env: Env) { this.storage = state.storage; this.id = state.id; this.doEverySeconds = 2; this.env = env; } async fetch() { const alarmTime = await this.storage.get("alarmTime"); console.log("alarmTime",alarmTime) if (!alarmTime) { await this.scheduleAlarm(); } else { return new Response("Water alarm is already scheduled."); } return new Response("Water schedule Successfully!"); } async alarm() { console.log("Water Alarm Doing"); await this.storage.delete("alarmTime"); } async scheduleAlarm() { let scheduledTime: number = Date.now() + this.doEverySeconds * 1000; await this.storage.put("alarmTime", scheduledTime.toString()); this.storage.setAlarm(scheduledTime); } } for example:- first-time call schedule: alarm calling 2s: alarm calling 4s: alarm calling 6s: alarm calling when I recall the API, it is already scheduled already doing 8s: alarm calling 10s: alarm calling continue OR first time call schudle: alarm calling 2s: alarm calling 4s: alarm calling 6s: alarm calling
omar4289
omar428913mo ago
Ok, I get it So, here the new code 1. const doId = env.WATER.newUniqueId(); must be replaced with env.WATER.idFromName('water_instance'). The reason is that you have different DO instance per call if you use newUniqueId(). Different instances means, different storage, they are not synced together .... 2. async alarm() { console.log("Water Alarm Doing"); await this.scheduleAlarm(); }
Harshil Bodara
Harshil BodaraOP13mo ago
he said, water schdule already working so how may i stop and again run?
No description
No description
omar4289
omar428913mo ago
Ok, if you want to manage the state of your waterfall, here is a better solution
Harshil Bodara
Harshil BodaraOP13mo ago
yes, let me know
omar4289
omar428913mo ago
@Harshil Bodara
router.get('/water/start', async (request: Request, env: Env) => {
const doId = env.WATER.idFromName('water_instance');
const WaterInstance = env.WATER.get(doId);
return WaterInstance.fetch(request);
});

router.get('/water/stop', async (request: Request, env: Env) => {
const doId = env.WATER.idFromName('water_instance');
const WaterInstance = env.WATER.get(doId);
return WaterInstance.fetch(request);
});
router.get('/water/start', async (request: Request, env: Env) => {
const doId = env.WATER.idFromName('water_instance');
const WaterInstance = env.WATER.get(doId);
return WaterInstance.fetch(request);
});

router.get('/water/stop', async (request: Request, env: Env) => {
const doId = env.WATER.idFromName('water_instance');
const WaterInstance = env.WATER.get(doId);
return WaterInstance.fetch(request);
});
export class Water {
id: string | DurableObjectId;
storage: DurableObjectStorage;
doEverySeconds: number;
env: Env;

constructor(state: DurableObjectState, env: Env) {
this.storage = state.storage;
this.id = state.id;
this.doEverySeconds = 2;
this.env = env;
}

async fetch(request: Request) {
const url = new URL(request.url);
const action = url.pathname.split('/')[2];

switch (action) {
case 'start':
const alarmTime = await this.storage.get('alarmTime');
if (!alarmTime) {
await this.scheduleAlarm();
return new Response('Water schedule Successfully!');
} else {
return new Response('Water alarm is already scheduled.');
}
case 'stop':
await this.storage.deleteAlarm();
await this.storage.delete('alarmTime');
return new Response("Water alarm stopped");
default:
return new Response('', { status: 404 });
}
}

async alarm() {
console.log('Water Alarm Doing');
await this.scheduleAlarm();
}

async scheduleAlarm() {
let scheduledTime: number = Date.now() + this.doEverySeconds * 1000;
await this.storage.put('alarmTime', scheduledTime.toString());
await this.storage.setAlarm(scheduledTime);
}
}
export class Water {
id: string | DurableObjectId;
storage: DurableObjectStorage;
doEverySeconds: number;
env: Env;

constructor(state: DurableObjectState, env: Env) {
this.storage = state.storage;
this.id = state.id;
this.doEverySeconds = 2;
this.env = env;
}

async fetch(request: Request) {
const url = new URL(request.url);
const action = url.pathname.split('/')[2];

switch (action) {
case 'start':
const alarmTime = await this.storage.get('alarmTime');
if (!alarmTime) {
await this.scheduleAlarm();
return new Response('Water schedule Successfully!');
} else {
return new Response('Water alarm is already scheduled.');
}
case 'stop':
await this.storage.deleteAlarm();
await this.storage.delete('alarmTime');
return new Response("Water alarm stopped");
default:
return new Response('', { status: 404 });
}
}

async alarm() {
console.log('Water Alarm Doing');
await this.scheduleAlarm();
}

async scheduleAlarm() {
let scheduledTime: number = Date.now() + this.doEverySeconds * 1000;
await this.storage.put('alarmTime', scheduledTime.toString());
await this.storage.setAlarm(scheduledTime);
}
}
Harshil Bodara
Harshil BodaraOP13mo ago
Thank you, @omar , It was a very exciting good solution now schedule is working fine
omar4289
omar428913mo ago
You are welcome You should still add more control in case your alarm did stop - For example, on run, if the alarm did not execute since 60minutes, then just rerun it instead of returning already scheduled
Harshil Bodara
Harshil BodaraOP13mo ago
Thank you So much! @omar yes, i got it
Want results from more Discord servers?
Add your server