Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 30 additions & 0 deletions src/main/java/io/temporal/samples/moneybatch/Account.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/*
* 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.moneybatch;

import io.temporal.activity.ActivityInterface;

@ActivityInterface
public interface Account {

void deposit(String accountId, String referenceId, int amountCents);

void withdraw(String accountId, String referenceId, int amountCents);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
/*
* 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.moneybatch;

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

public class AccountActivityWorker {

static final String TASK_LIST = "Account";

@SuppressWarnings("CatchAndPrintStackTrace")
public static void main(String[] args) {
WorkflowServiceStubs service = WorkflowServiceStubs.newInstance();
WorkflowClient client = WorkflowClient.newInstance(service);

WorkerFactory factory = WorkerFactory.newInstance(client);
Worker worker = factory.newWorker(TASK_LIST);

Account account = new AccountImpl();
worker.registerActivitiesImplementations(account);

factory.start();
System.out.println("Activity Worker started for task list: " + TASK_LIST);
}
}
37 changes: 37 additions & 0 deletions src/main/java/io/temporal/samples/moneybatch/AccountImpl.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/*
* 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.moneybatch;

public class AccountImpl implements Account {
@Override
public void deposit(String accountId, String referenceId, int amountCents) {
System.out.printf(
"Deposit to %s of %d cents requested. ReferenceId=%s\n",
accountId, amountCents, referenceId);
// throw new RuntimeException("simulated"); // Uncomment to simulate failure
}

@Override
public void withdraw(String accountId, String referenceId, int amountCents) {
System.out.printf(
"Withdraw to %s of %d cents requested. ReferenceId=%s\n",
accountId, amountCents, referenceId);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/*
* 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.moneybatch;

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

public class AccountTransferWorker {

@SuppressWarnings("CatchAndPrintStackTrace")
public static void main(String[] args) {
WorkflowServiceStubs service = WorkflowServiceStubs.newInstance();
WorkflowClient client = WorkflowClient.newInstance(service);
WorkerFactory factory = WorkerFactory.newInstance(client);

Worker worker = factory.newWorker(AccountActivityWorker.TASK_LIST);
worker.registerWorkflowImplementationTypes(AccountTransferWorkflowImpl.class);

factory.start();
System.out.println("Worker started for task list: " + AccountActivityWorker.TASK_LIST);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/*
* 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.moneybatch;

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

@WorkflowInterface
public interface AccountTransferWorkflow {

@WorkflowMethod
void deposit(String toAccountId, int batchSize);

@SignalMethod
void withdraw(String fromAccountId, String referenceId, int amountCents);

@QueryMethod
int getBalance();

@QueryMethod
int getCount();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
/*
* 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.moneybatch;

import io.temporal.activity.ActivityOptions;
import io.temporal.common.RetryOptions;
import io.temporal.workflow.Workflow;
import java.time.Duration;
import java.util.HashSet;
import java.util.Set;

public class AccountTransferWorkflowImpl implements AccountTransferWorkflow {

private final ActivityOptions options =
ActivityOptions.newBuilder()
.setStartToCloseTimeout(Duration.ofSeconds(5))
.setScheduleToStartTimeout(Duration.ofHours(1))
.setRetryOptions(
RetryOptions.newBuilder()
.setInitialInterval(Duration.ofSeconds(1))
.setMaximumInterval(Duration.ofSeconds(10))
.build())
.build();

private final Account account = Workflow.newActivityStub(Account.class, options);

private Set<String> references = new HashSet<>();
private int balance;
private int count;

@Override
public void deposit(String toAccount, int batchSize) {
Workflow.await(() -> count == batchSize);
String referenceId = Workflow.randomUUID().toString();
account.deposit(toAccount, referenceId, balance);
}

@Override
public void withdraw(String fromAccountId, String referenceId, int amountCents) {
if (!references.add(referenceId)) {
return; // duplicate
}
account.withdraw(fromAccountId, referenceId, amountCents);
balance += amountCents;
count++;
}

@Override
public int getBalance() {
return balance;
}

@Override
public int getCount() {
return count;
}
}
17 changes: 17 additions & 0 deletions src/main/java/io/temporal/samples/moneybatch/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Demonstrates Signal Batching

The sample demonstrates a situation when a single deposit should be initiated for multiple
withdrawals. For example a seller might want to be paid once per fixed number of transactions.
The sample can be easily extended to perform a payment based on a more complex criteria like a
specific time or accumulated amount.

The sample also demonstrates _signal with start_ way of starting workflows. If workflow is already
running it just receives a signal. If it is not running then it is started first and then signal is
delivered to it. You can think about _signal with start_ as a lazy way to create workflows when
signalling them.

To run a worker that hosts the workflow code execute:




Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
/*
* 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.moneybatch;

import io.temporal.client.BatchRequest;
import io.temporal.client.WorkflowClient;
import io.temporal.client.WorkflowOptions;
import io.temporal.serviceclient.WorkflowServiceStubs;
import java.util.Random;
import java.util.UUID;

public class TransferRequester {

/** Number of withdrawals to batch */
public static final int BATCH_SIZE = 3;

@SuppressWarnings("CatchAndPrintStackTrace")
public static void main(String[] args) {
String reference = UUID.randomUUID().toString();
int amountCents = (new Random().nextInt(5) + 1) * 25;
WorkflowServiceStubs service = WorkflowServiceStubs.newInstance();
WorkflowClient workflowClient = WorkflowClient.newInstance(service);

String from = "account1";
String to = "account2";
WorkflowOptions options =
WorkflowOptions.newBuilder()
.setTaskList(AccountActivityWorker.TASK_LIST)
.setWorkflowId(to)
.build();
AccountTransferWorkflow transferWorkflow =
workflowClient.newWorkflowStub(AccountTransferWorkflow.class, options);
// Signal with start sends a signal to a workflow starting it if not yet running
BatchRequest request = workflowClient.newSignalWithStartRequest();
request.add(transferWorkflow::deposit, to, BATCH_SIZE);
request.add(transferWorkflow::withdraw, from, reference, amountCents);
workflowClient.signalWithStart(request);

System.out.printf("Transfer of %d cents from %s to %s requested", amountCents, from, to);
System.exit(0);
}
}
30 changes: 30 additions & 0 deletions src/main/java/io/temporal/samples/moneytransfer/Account.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/*
* 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.moneytransfer;

import io.temporal.activity.ActivityInterface;

@ActivityInterface
public interface Account {

void deposit(String accountId, String referenceId, int amountCents);

void withdraw(String accountId, String referenceId, int amountCents);
}
Loading