Skip to content

Commit 0bcd2e8

Browse files
committed
Added test cases
Signed-off-by: Amulya Varote <[email protected]> Signed-off-by: Amulya Varote <[email protected]>
1 parent 1a8dff0 commit 0bcd2e8

File tree

9 files changed

+176
-12
lines changed

9 files changed

+176
-12
lines changed

daprdocs/content/en/js-sdk-docs/js-actors/_index.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,7 @@ async function start()
159159
callback: "method-to-excute-on-actor",
160160
dueTime: Temporal.Duration.from({ seconds: 2 }),
161161
period: Temporal.Duration.from({ seconds: 1 }),
162-
ttl?: Temporal.Duration.from({ seconds: 1 }),
162+
ttl: Temporal.Duration.from({ seconds: 1 }),
163163
});
164164

165165
// Delete the timer
@@ -185,7 +185,7 @@ async function start()
185185
await client.actor.reminderCreate(DemoActorImpl.name, `actor-id`, `timer-id`, {
186186
dueTime: Temporal.Duration.from({ seconds: 2 }),
187187
period: Temporal.Duration.from({ seconds: 1 }),
188-
ttl?: Temporal.Duration.from({ seconds: 1 }),
188+
ttl: Temporal.Duration.from({ seconds: 1 }),
189189
data: 100
190190
});
191191

src/actors/runtime/AbstractActor.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -80,12 +80,12 @@ export default abstract class AbstractActor {
8080
* @param reminderName name of the reminder
8181
* @param state the state to be send along with the reminder trigger
8282
* @param dueTime due time for the first trigger
83-
* @param ttl time to live
83+
* @param ttl time to duration after which the reminder will be expired and deleted
8484
* @param period frequency for the triggers
8585
* @param <Type> Type of the state object
8686
* @return Async void response
8787
*/
88-
async registerActorReminder<_Type>(reminderName: string, dueTime: Temporal.Duration, ttl: Temporal.Duration, period: Temporal.Duration, state?: any) {
88+
async registerActorReminder<_Type>(reminderName: string, dueTime: Temporal.Duration, period: Temporal.Duration, ttl?: Temporal.Duration, state?: any) {
8989
await this.actorClient.actor.registerActorReminder(this.actorType, this.id, reminderName, {
9090
period,
9191
dueTime,
@@ -98,7 +98,7 @@ export default abstract class AbstractActor {
9898
await this.actorClient.actor.unregisterActorReminder(this.actorType, this.id, reminderName);
9999
}
100100

101-
async registerActorTimer(timerName: string, callback: string, dueTime: Temporal.Duration, ttl: Temporal.Duration, period: Temporal.Duration, state?: any) {
101+
async registerActorTimer(timerName: string, callback: string, dueTime: Temporal.Duration, period: Temporal.Duration, ttl?: Temporal.Duration, state?: any) {
102102
// Register the timer in the sidecar
103103
return await this.actorClient.actor.registerActorTimer(this.actorType, this.id, timerName, {
104104
period,

src/actors/runtime/ActorReminderData.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,17 +20,17 @@ export default class ActorReminderData {
2020
readonly reminderName: string;
2121
readonly state: string | object | undefined;
2222
readonly dueTime: number;
23-
readonly ttl: number;
23+
readonly ttl: number | undefined;
2424
readonly period: number;
2525

2626
/**
2727
* @param reminderName the name of the actor reminder
2828
* @param state the state data passed to receiveReminder callback
2929
* @param dueTime the amount of time to delay before invoking the reminder for the first time
30-
* @param ttl time to live
30+
* @param ttl time to duration after which the reminder will be expired and deleted
3131
* @param period the time interval between reminder invocations after the first invocation
3232
*/
33-
constructor(reminderName: string, dueTime: number, ttl: number, period: number, state?: string | object) {
33+
constructor(reminderName: string, dueTime: number, period: number, ttl?: number, state?: string | object) {
3434
this.reminderName = reminderName;
3535
this.dueTime = dueTime;
3636
this.ttl = ttl;
@@ -50,7 +50,7 @@ export default class ActorReminderData {
5050
return this.dueTime;
5151
}
5252

53-
getTtl(): number {
53+
getTtl(): number | undefined {
5454
return this.ttl;
5555
}
5656

test/actor/DemoActorReminder2Impl.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,8 @@ export default class DemoActorReminder2Impl extends AbstractActor implements Dem
1818
counter = 0;
1919

2020
async init(): Promise<string> {
21-
await super.registerActorReminder("my-reminder-name", Temporal.Duration.from({ seconds: 2 }), Temporal.Duration.from({ seconds: 2 }), Temporal.Duration.from({ seconds: 1 }), 123);
21+
await super.registerActorReminder("my-reminder-name", Temporal.Duration.from({ seconds: 2 }), Temporal.Duration.from({ seconds: 2 }),
22+
Temporal.Duration.from({ seconds: 1 }), 123);
2223
return "Actor Initialized";
2324
}
2425

test/actor/DemoActorReminderImpl.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,8 @@ export default class DemoActorReminderImpl extends AbstractActor implements Demo
1818
counter = 0;
1919

2020
async init(): Promise<string> {
21-
await super.registerActorReminder("my-reminder-name", Temporal.Duration.from({ seconds: 2 }), Temporal.Duration.from({ seconds: 2 }), Temporal.Duration.from({ seconds: 1 }), 123);
21+
await super.registerActorReminder("my-reminder-name", Temporal.Duration.from({ seconds: 2 }), Temporal.Duration.from({ seconds: 2 }),
22+
Temporal.Duration.from({ seconds: 1 }), 123);
2223
return "Actor Initialized";
2324
}
2425

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
/*
2+
Copyright 2022 The Dapr Authors
3+
Licensed under the Apache License, Version 2.0 (the "License");
4+
you may not use this file except in compliance with the License.
5+
You may obtain a copy of the License at
6+
http://www.apache.org/licenses/LICENSE-2.0
7+
Unless required by applicable law or agreed to in writing, software
8+
distributed under the License is distributed on an "AS IS" BASIS,
9+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10+
See the License for the specific language governing permissions and
11+
limitations under the License.
12+
*/
13+
14+
import { AbstractActor, Temporal } from "../../src";
15+
import DemoActorReminderInterface from "./DemoActorReminderInterface";
16+
17+
export default class DemoActorReminderTtlImpl extends AbstractActor implements DemoActorReminderInterface {
18+
counter = 0;
19+
20+
async init(): Promise<string> {
21+
await super.registerActorReminder("my-reminder-name",
22+
Temporal.Duration.from({ seconds: 2 }), //dueTime
23+
Temporal.Duration.from({ seconds: 0.5 }), //period
24+
Temporal.Duration.from({ seconds: 0.5 }), //ttl
25+
123);
26+
return "Actor Initialized";
27+
}
28+
29+
async count(): Promise<void> {
30+
this.counter++;
31+
}
32+
33+
async getCounter(): Promise<number> {
34+
return this.counter;
35+
}
36+
37+
async removeReminder(): Promise<void> {
38+
return this.unregisterActorReminder("my-reminder-name");
39+
}
40+
41+
/**
42+
* @override
43+
* @param data
44+
*/
45+
async receiveReminder(data: string): Promise<void> {
46+
this.counter += parseInt(data);
47+
}
48+
}

test/actor/DemoActorTimerImpl.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,8 @@ export default class DemoActorTimerImpl extends AbstractActor implements DemoAct
1818
counter = 0;
1919

2020
async init(): Promise<string> {
21-
await super.registerActorTimer("my-timer-name", "countBy", Temporal.Duration.from({ seconds: 2 }), Temporal.Duration.from({ seconds: 2 }), Temporal.Duration.from({ seconds: 1 }), 100);
21+
await super.registerActorTimer("my-timer-name", "countBy", Temporal.Duration.from({ seconds: 2 }), Temporal.Duration.from({ seconds: 1 }),
22+
undefined, 100);
2223
return "Actor Initialized";
2324
}
2425

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
/*
2+
Copyright 2022 The Dapr Authors
3+
Licensed under the Apache License, Version 2.0 (the "License");
4+
you may not use this file except in compliance with the License.
5+
You may obtain a copy of the License at
6+
http://www.apache.org/licenses/LICENSE-2.0
7+
Unless required by applicable law or agreed to in writing, software
8+
distributed under the License is distributed on an "AS IS" BASIS,
9+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10+
See the License for the specific language governing permissions and
11+
limitations under the License.
12+
*/
13+
14+
import { AbstractActor, Temporal } from "../../src";
15+
import DemoActorTimerInterface from "./DemoActorTimerInterface";
16+
17+
export default class DemoActorTimerTtlImpl extends AbstractActor implements DemoActorTimerInterface {
18+
counter = 0;
19+
20+
async init(): Promise<string> {
21+
await super.registerActorTimer("my-timer-name", "countBy",
22+
Temporal.Duration.from({ seconds: 2 }), //dueTime
23+
Temporal.Duration.from({ seconds: 0.5 }), //period
24+
Temporal.Duration.from({ seconds: 0.5 }), //ttl
25+
100);
26+
return "Actor Initialized";
27+
}
28+
29+
async count(): Promise<void> {
30+
this.counter++;
31+
}
32+
33+
async getCounter(): Promise<number> {
34+
return this.counter;
35+
}
36+
37+
async countBy(amount: string): Promise<void> {
38+
this.counter += parseInt(amount);
39+
}
40+
41+
async removeTimer(): Promise<void> {
42+
return await this.unregisterActorTimer("my-timer-name");
43+
}
44+
}

test/e2e/actors.http.test.ts

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ import DemoActorSayImpl from '../actor/DemoActorSayImpl';
2626
import DemoActorSayInterface from '../actor/DemoActorSayInterface';
2727
import DemoActorTimerImpl from '../actor/DemoActorTimerImpl';
2828
import DemoActorTimerInterface from '../actor/DemoActorTimerInterface';
29+
import DemoActorTimerTtlImpl from '../actor/DemoActorTimerTtlImpl';
30+
import DemoActorReminderTtlImpl from '../actor/DemoActorReminderTtlImpl';
2931

3032
const serverHost = "127.0.0.1";
3133
const serverPort = "50001";
@@ -171,6 +173,42 @@ describe('http/actors', () => {
171173
const res4 = await actor.getCounter();
172174
expect(res4).toEqual(300);
173175
}, 10000);
176+
177+
178+
it('should apply the ttl when it is set (expected execution time > 5s)', async () => {
179+
const builder = new ActorProxyBuilder<DemoActorTimerInterface>(DemoActorTimerTtlImpl, client);
180+
const actor = builder.build(ActorId.createRandomId());
181+
182+
// Activate our actor
183+
await actor.init();
184+
185+
const res0 = await actor.getCounter();
186+
expect(res0).toEqual(0);
187+
188+
// Now we wait for dueTime (2s)
189+
await (new Promise(resolve => setTimeout(resolve, 500)));
190+
191+
// After that the timer callback will be called
192+
// In our case, the callback increments the count attribute
193+
// the count attribute is +100 due to the passed state
194+
const res1 = await actor.getCounter();
195+
expect(res1).toEqual(100);
196+
197+
// Every 1 second the timer gets called again, so the count attribute should change
198+
// we check this twice to ensure correct calling
199+
await (new Promise(resolve => setTimeout(resolve, 500)));
200+
const res2 = await actor.getCounter();
201+
expect(res2).toEqual(200);
202+
203+
await (new Promise(resolve => setTimeout(resolve, 500)));
204+
try {
205+
const res3 = await actor.getCounter();
206+
} catch(e) {
207+
//@ts-ignore
208+
console.log(e.message)
209+
}
210+
// expect(res3).toEqual(300);
211+
}, 10000);
174212
});
175213

176214
describe('reminders', () => {
@@ -228,5 +266,36 @@ describe('http/actors', () => {
228266
// Unregister the reminder
229267
await actor.removeReminder();
230268
});
269+
270+
it('should apply the ttl when it is set to a reminder', async () => {
271+
const builder = new ActorProxyBuilder<DemoActorReminderInterface>(DemoActorReminderTtlImpl, client);
272+
const actor = builder.build(ActorId.createRandomId());
273+
274+
// Activate our actor
275+
// this will initialize the reminder to be called
276+
await actor.init();
277+
278+
const res0 = await actor.getCounter();
279+
expect(res0).toEqual(0);
280+
281+
// Now we wait for dueTime (2s)
282+
await NodeJSUtil.sleep(2000);
283+
284+
// After that the reminder callback will be called
285+
// In our case, the callback increments the count attribute
286+
const res1 = await actor.getCounter();
287+
expect(res1).toEqual(123);
288+
289+
await actor.removeReminder();
290+
291+
await (new Promise(resolve => setTimeout(resolve, 500)));
292+
try {
293+
const res2 = await actor.getCounter();
294+
} catch(e) {
295+
//@ts-ignore
296+
console.log(e.message)
297+
}
298+
// expect(res2).toEqual(123);
299+
});
231300
});
232301
});

0 commit comments

Comments
 (0)