Skip to content

Commit

Permalink
Add sleepfordays sample (#709)
Browse files Browse the repository at this point in the history
* Add sleepfordays sample

* remove extra semicolon
  • Loading branch information
THardy98 authored Jan 31, 2025
1 parent 30db7db commit 1b1a632
Show file tree
Hide file tree
Showing 8 changed files with 324 additions and 0 deletions.
17 changes: 17 additions & 0 deletions core/src/main/java/io/temporal/samples/sleepfordays/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Sleep for days

This sample demonstrates how to use Temporal to run a workflow that periodically sleeps for a number of days.

## Run the sample

1. Start the Worker:

```bash
./gradlew -q execute -PmainClass=io.temporal.samples.sleepfordays.Worker
```

2. Start the Starter

```bash
./gradlew -q execute -PmainClass=io.temporal.samples.sleepfordays.Starter
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/*
* Copyright (c) 2020 Temporal Technologies, Inc. All Rights Reserved
*
* Copyright 2012-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Modifications copyright (C) 2017 Uber Technologies, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"). You may not
* use this file except in compliance with the License. A copy of the License is
* located at
*
* http://aws.amazon.com/apache2.0
*
* or in the "license" file accompanying this file. This file is distributed on
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
* express or implied. See the License for the specific language governing
* permissions and limitations under the License.
*/

package io.temporal.samples.sleepfordays;

import io.temporal.activity.ActivityInterface;

@ActivityInterface
public interface SendEmailActivity {
void sendEmail(String email);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/*
* Copyright (c) 2020 Temporal Technologies, Inc. All Rights Reserved
*
* Copyright 2012-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Modifications copyright (C) 2017 Uber Technologies, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"). You may not
* use this file except in compliance with the License. A copy of the License is
* located at
*
* http://aws.amazon.com/apache2.0
*
* or in the "license" file accompanying this file. This file is distributed on
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
* express or implied. See the License for the specific language governing
* permissions and limitations under the License.
*/

package io.temporal.samples.sleepfordays;

public class SendEmailActivityImpl implements SendEmailActivity {
@Override
public void sendEmail(String email) {
System.out.println(email);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
/*
* Copyright (c) 2020 Temporal Technologies, Inc. All Rights Reserved
*
* Copyright 2012-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Modifications copyright (C) 2017 Uber Technologies, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"). You may not
* use this file except in compliance with the License. A copy of the License is
* located at
*
* http://aws.amazon.com/apache2.0
*
* or in the "license" file accompanying this file. This file is distributed on
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
* express or implied. See the License for the specific language governing
* permissions and limitations under the License.
*/

package io.temporal.samples.sleepfordays;

import io.temporal.activity.ActivityOptions;
import io.temporal.workflow.Promise;
import io.temporal.workflow.Workflow;
import java.time.Duration;

public class SleepForDaysImpl implements SleepForDaysWorkflow {

private final SendEmailActivity activity;
private boolean complete = false;

public SleepForDaysImpl() {
this.activity =
Workflow.newActivityStub(
SendEmailActivity.class,
ActivityOptions.newBuilder().setStartToCloseTimeout(Duration.ofSeconds(10)).build());
}

@Override
public String sleepForDays() {
while (!this.complete) {
activity.sendEmail(String.format("Sleeping for 30 days"));
Promise<Void> timer = Workflow.newTimer(Duration.ofDays(30));
Workflow.await(() -> timer.isCompleted() || this.complete);
}

return "done!";
}

@Override
public void complete() {
this.complete = true;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/*
* Copyright (c) 2020 Temporal Technologies, Inc. All Rights Reserved
*
* Copyright 2012-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Modifications copyright (C) 2017 Uber Technologies, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"). You may not
* use this file except in compliance with the License. A copy of the License is
* located at
*
* http://aws.amazon.com/apache2.0
*
* or in the "license" file accompanying this file. This file is distributed on
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
* express or implied. See the License for the specific language governing
* permissions and limitations under the License.
*/

package io.temporal.samples.sleepfordays;

import io.temporal.workflow.SignalMethod;
import io.temporal.workflow.WorkflowInterface;
import io.temporal.workflow.WorkflowMethod;

@WorkflowInterface
public interface SleepForDaysWorkflow {
@WorkflowMethod
String sleepForDays();

@SignalMethod
void complete();
}
46 changes: 46 additions & 0 deletions core/src/main/java/io/temporal/samples/sleepfordays/Starter.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
/*
* Copyright (c) 2020 Temporal Technologies, Inc. All Rights Reserved
*
* Copyright 2012-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Modifications copyright (C) 2017 Uber Technologies, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"). You may not
* use this file except in compliance with the License. A copy of the License is
* located at
*
* http://aws.amazon.com/apache2.0
*
* or in the "license" file accompanying this file. This file is distributed on
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
* express or implied. See the License for the specific language governing
* permissions and limitations under the License.
*/

package io.temporal.samples.sleepfordays;

import io.temporal.client.WorkflowClient;
import io.temporal.client.WorkflowOptions;
import io.temporal.client.WorkflowStub;

public class Starter {

public static final String TASK_QUEUE = "SleepForDaysTaskQueue";

public static void main(String[] args) {
// Start a workflow execution.
SleepForDaysWorkflow workflow =
Worker.client.newWorkflowStub(
SleepForDaysWorkflow.class,
WorkflowOptions.newBuilder().setTaskQueue(TASK_QUEUE).build());

// Start the workflow.
WorkflowClient.start(workflow::sleepForDays);

WorkflowStub stub = WorkflowStub.fromTyped(workflow);

// Wait for workflow to complete. This will wait indefinitely until a 'complete' signal is sent.
stub.getResult(String.class);
System.exit(0);
}
}
40 changes: 40 additions & 0 deletions core/src/main/java/io/temporal/samples/sleepfordays/Worker.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/*
* Copyright (c) 2020 Temporal Technologies, Inc. All Rights Reserved
*
* Copyright 2012-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Modifications copyright (C) 2017 Uber Technologies, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"). You may not
* use this file except in compliance with the License. A copy of the License is
* located at
*
* http://aws.amazon.com/apache2.0
*
* or in the "license" file accompanying this file. This file is distributed on
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
* express or implied. See the License for the specific language governing
* permissions and limitations under the License.
*/

package io.temporal.samples.sleepfordays;

import io.temporal.client.WorkflowClient;
import io.temporal.serviceclient.WorkflowServiceStubs;
import io.temporal.worker.WorkerFactory;

public class Worker {
public static final String TASK_QUEUE = "SleepForDaysTaskQueue";
public static final WorkflowServiceStubs service = WorkflowServiceStubs.newLocalServiceStubs();
public static final WorkflowClient client = WorkflowClient.newInstance(service);
public static final WorkerFactory factory = WorkerFactory.newInstance(client);

public static void main(String[] args) {
io.temporal.worker.Worker worker = factory.newWorker(TASK_QUEUE);
worker.registerWorkflowImplementationTypes(SleepForDaysImpl.class);
worker.registerActivitiesImplementations(new SendEmailActivityImpl());

factory.start();
System.out.println("Worker started for task queue: " + TASK_QUEUE);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
/*
* Copyright (c) 2020 Temporal Technologies, Inc. All Rights Reserved
*
* Copyright 2012-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Modifications copyright (C) 2017 Uber Technologies, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"). You may not
* use this file except in compliance with the License. A copy of the License is
* located at
*
* http://aws.amazon.com/apache2.0
*
* or in the "license" file accompanying this file. This file is distributed on
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
* express or implied. See the License for the specific language governing
* permissions and limitations under the License.
*/

package io.temporal.samples.sleepfordays;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;

import io.temporal.client.WorkflowClient;
import io.temporal.client.WorkflowOptions;
import io.temporal.testing.TestWorkflowRule;
import java.time.Duration;
import org.junit.Rule;
import org.junit.Test;

public class SleepForDaysTest {

@Rule
public TestWorkflowRule testWorkflowRule =
TestWorkflowRule.newBuilder()
.setWorkflowTypes(SleepForDaysImpl.class)
.setDoNotStart(true)
.build();

@Test(timeout = 8000)
public void testSleepForDays() {
// Mock activity
SendEmailActivity activities = mock(SendEmailActivity.class);
testWorkflowRule.getWorker().registerActivitiesImplementations(activities);
// Start environment
testWorkflowRule.getTestEnvironment().start();

// Create a workflow
WorkflowOptions workflowOptions =
WorkflowOptions.newBuilder().setTaskQueue(testWorkflowRule.getTaskQueue()).build();
SleepForDaysWorkflow workflow =
testWorkflowRule
.getWorkflowClient()
.newWorkflowStub(SleepForDaysWorkflow.class, workflowOptions);

// Start workflow
WorkflowClient.start(workflow::sleepForDays);

long startTime = testWorkflowRule.getTestEnvironment().currentTimeMillis();
// Time-skip 5 minutes.
testWorkflowRule.getTestEnvironment().sleep(Duration.ofMinutes(5));
// Check that the activity has been called, we're now waiting for the sleep to finish.
verify(activities, times(1)).sendEmail(anyString());
// Time-skip 3 days.
testWorkflowRule.getTestEnvironment().sleep(Duration.ofDays(90));
// Expect 3 more activity calls.
verify(activities, times(4)).sendEmail(anyString());
// Send the signal to complete the workflow.
workflow.complete();
// Expect no more activity calls to have been made - workflow is complete.
verify(activities, times(4)).sendEmail(anyString());
// Expect more than 90 days to have passed.
long endTime = testWorkflowRule.getTestEnvironment().currentTimeMillis();
assertEquals(true, endTime - startTime > Duration.ofDays(90).toMillis());
}
}

0 comments on commit 1b1a632

Please sign in to comment.