Git Product home page Git Product logo

cadence-java-client's Introduction

Java framework for Cadence Build Status Javadocs Coverage Status

Cadence is a distributed, scalable, durable, and highly available orchestration engine we developed at Uber Engineering to execute asynchronous long-running business logic in a scalable and resilient way.

cadence-client is the framework for authoring workflows and activities in Java.

If you are authoring in Go, see Go Cadence Client.

Samples

For samples, see Samples for the Java Cadence client.

Run Cadence Server

Run Cadence Server using Docker Compose:

curl -O https://raw.githubusercontent.com/uber/cadence/master/docker/docker-compose.yml
docker-compose up

If this does not work, see instructions for running the Cadence Server at https://github.com/uber/cadence/blob/master/README.md.

Get CLI

CLI is avaialable as an executable or as a docker image

Build a configuration

Add cadence-client as a dependency to your pom.xml:

<dependency>
  <groupId>com.uber.cadence</groupId>
  <artifactId>cadence-client</artifactId>
  <version>V.V.V</version>
</dependency>

or to build.gradle:

compile group: 'com.uber.cadence', name: 'cadence-client', version: 'V.V.V'

Documentation

The documentation on how to use the Cadence Java client is here.

Javadocs for the client API are located here.

Contributing

We'd love your help in making the Cadence Java client great. Please review our contribution guidelines.

License

Apache License, please see LICENSE for details.

cadence-java-client's People

Contributors

abhishekj720 avatar andrewjdawson2016 avatar demirkayaender avatar denyska avatar dmetzgar avatar duoertai avatar emrahs avatar groxx avatar halakaraki avatar longquanzheng avatar meiliang86 avatar mfateev avatar mindaugasbarcauskas avatar mkolodezny avatar mstifflin avatar natemort avatar nlremco avatar pgoron avatar purplesusan avatar sdwr98 avatar shaddoll avatar shijiesheng avatar sokada1221 avatar spmistry avatar uberzydins avatar vancexu avatar vytautas-karpavicius avatar yashrajbharti avatar yux0 avatar yycptt avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

cadence-java-client's Issues

Replaying the whole history fails with "missing replay decision for WorkflowExecutionCompleted"

Customer reported:

I'm upgrading my team's service to use cadencefx instead of a non-standard implementation from before. I was recommended using ReplayWorkflow to ensure that nothing breaks.
I was able to get the workflow history as JSON but I get this error:
nondeterministic workflow: missing replay decision for WorkflowExecutionCompleted: (Result:[], DecisionTaskCompletedEventId:26)
These are the last two events in the history:

  {
        "eventId": 26,
        "timestamp": 1537253999278302610,
        "eventType": "DecisionTaskCompleted",
        "decisionTaskCompletedEventAttributes": {
            "scheduledEventId": 24,
            "startedEventId": 25,
            "identity": "128@compute3435-sjc1@deferred-dispatch"
        }
    },
    {
        "eventId": 27,
        "timestamp": 1537253999278309160,
        "eventType": "WorkflowExecutionCompleted",
        "workflowExecutionCompletedEventAttributes": {
            "decisionTaskCompletedEventId": 26
        }
    }

Add support for passing configuration to the workflow implemenation

Currently to pass configuration to a workflow it has to be passed as an argument, loaded in an activity or in a SideEffect (which can access only global static methods).

The proposal is to support passing a configuration object instance to a workflow instance.
The possible API:

WorkerOptions o = new WorkerOptions.Builder().setConfig(config).build();

and inside a workflow code:

ConfigClass config = Workflow.getConfig(ConfigClass.class);

or even inject it into a workflow instance field.

ConcurrentModificationException causing decision task failure

ConcurrentModificationException will be thrown when user tries to cancel workflow and workflow has uncatched exception. More specifically, DeterministicRunnerImpl.close() loops all failedPromises and call promise.get(). CompletablePromiseImpl get will try to call forgetFailedPromise and modify the set on failure. Hence the exception.

When this happens decision task will fail and the workflow will stuck.

We need to avoid promise de-register on DeterministicRunnerImpl.close, or use iterator to loop through the set so remove is allowed.

Call stack

ERROR [2018-08-06 18:59:01,881] com.uber.cadence.internal.worker.PollerOptions: uncaught exception
! java.util.ConcurrentModificationException: null
! at java.util.HashMap$HashIterator.nextNode(HashMap.java:1437)
! at java.util.HashMap$KeyIterator.next(HashMap.java:1461)
! at com.uber.cadence.internal.sync.DeterministicRunnerImpl.close(DeterministicRunnerImpl.java:280)
! at com.uber.cadence.internal.sync.SyncWorkflow.close(SyncWorkflow.java:111)
! at com.uber.cadence.internal.replay.ReplayDecider.decideImpl(ReplayDecider.java:391)
! at com.uber.cadence.internal.replay.ReplayDecider.decide(ReplayDecider.java:355)
! at com.uber.cadence.internal.replay.ReplayDecisionTaskHandler.handleDecisionTaskImpl(ReplayDecisionTaskHandler.java:120)
! at com.uber.cadence.internal.replay.ReplayDecisionTaskHandler.handleDecisionTask(ReplayDecisionTaskHandler.java:62)
! at com.uber.cadence.internal.worker.WorkflowWorker$TaskHandlerImpl.handle(WorkflowWorker.java:200)
! at com.uber.cadence.internal.worker.WorkflowWorker$TaskHandlerImpl.handle(WorkflowWorker.java:181)
! at com.uber.cadence.internal.worker.PollTask.lambda$run$0(PollTask.java:102)
! ... 3 common frames omitted
! Causing: java.lang.RuntimeException: Failure processing decision task. WorkflowID=ucd-demo, RunID=281a9949-7dc0-4f13-b823-03dbd4e8b389
! at com.uber.cadence.internal.worker.WorkflowWorker$TaskHandlerImpl.wrapFailure(WorkflowWorker.java:278)
! at com.uber.cadence.internal.worker.WorkflowWorker$TaskHandlerImpl.wrapFailure(WorkflowWorker.java:181)
! at com.uber.cadence.internal.worker.PollTask.lambda$run$0(PollTask.java:107)
! at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
! at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
! at java.lang.Thread.run(Thread.java:748)

Change Java client to fail a decision instead of an API call for all argument checks

Currently specifying the wrong parameters to scheduling activity or a child workflow causes an exception that is thrown to a workflow code. While it sounds reasonable a bad code change might cause failures of workflows that might be running for a long time. The solution is to not to throw an application level exception, but an Error which leads to a decision failure. When decisions keep failing the workflows get stuck until the bug is fixed. This way a bad deployment is going to block workflow executions instead of failing them.

Thread Leak in Java Client

Determinister Runner waits on tasks inside locks on close. If the tasks have not yielded by the time close is a deadlock is triggered. This is more likely to happen with workflows with more concurrent activities.

Implement clean worker shutdown

When the worker shuts down and the interval passed to shutdown method is longer than the activity execution time there should not be activity timeouts.

Fetch full history on cache miss

Currently when there's a cache miss (we receive partial history for a workflow that's been evicted) we fail the decision. And the server has to dispatch the decision again. This causes a significant slowdown in performance (~10x)
Proposed solution: immediately fetch the full history when a cache miss happens so that the impact would be equivalent to not using a cache.

Support pagination in TestWorkflowService

Currently the test workflow service ignores any tokens/max page size on the request and will always return the full set of events. This is needed to unit test pagination

Add support for WorkerOptions NonDeterministicWorkflowPolicy

From Go client:

WorkerOptions struct {
                ...
                 // Optional: Sets how decision worker deals with non-deterministic history events
		// (presumably arising from non-deterministic workflow definitions or non-backward compatible workflow definition changes).
		// default: NonDeterministicWorkflowPolicyBlockWorkflow, which just logs error but reply nothing back to server
		NonDeterministicWorkflowPolicy NonDeterministicWorkflowPolicy
                 ...
}

Also consider to make it workflow type level config (may be even a property on @WorkflowMethod.)

Fix serialization and deserialization of collections of objects

Currently parameter of type List doesn't deserialize correctly. It happens because gson used to implement DataConverter doesn't have enough information about the type of the argument during deserialization. Current interface uses Class as a type passed to gson. The solution is to pass Type object returned from Method.getGenericParameterTypes(). The following code works:

  @Test
  public void testUUIDListGson() throws NoSuchMethodException {
    Method m = JsonDataConverterTest.class.getDeclaredMethod("foo", List.class);
    Type arg = m.getGenericParameterTypes()[0];
    GsonBuilder gsonBuilder =
        new GsonBuilder()
            .serializeNulls();
    Gson gson = gsonBuilder.create();

    List<UUID> list = new ArrayList<>();
    for (int i = 0; i < 2; i++) {
      list.add(UUID.randomUUID());
    }
    String data = gson.toJson(list);
    List<UUID> result = gson.fromJson(data, arg);
    assertEquals(result.toString(), list, result);
  }

The proposal is to change DataConverter API to either accept Method as a parameter or list of Type objects.

Implement multiple workflow versions through class loading

For relatively short running workflows keeping around multiple versions is a simpler model for developers than using Workflow#getVersion. In Java classloaders could be used to load multiple versions of the same class in the same process. This way a workflow would be packaged into an WAR like archive which would be loaded by workflow worker hosting process on demand.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.