Skip to content

Commit

Permalink
Rename Cadence to Temporal
Browse files Browse the repository at this point in the history
  • Loading branch information
antstorm committed Jun 5, 2020
1 parent 63c7b8f commit 34c02f6
Show file tree
Hide file tree
Showing 168 changed files with 787 additions and 800 deletions.
94 changes: 47 additions & 47 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,33 +1,33 @@
# Ruby worker for Cadence
# Ruby worker for Temporal [Under Development]

<img src="./assets/cadence_logo_2.png" width="250" align="right" alt="Cadence" />
<img src="./assets/temporal_logo.png" width="250" align="right" alt="Temporal" />

A pure Ruby library for defining and running Cadence workflows and activities.
A pure Ruby library for defining and running Temporal workflows and activities.

To find more about Cadence please visit <https://cadenceworkflow.io/>.
To find more about Temporal please visit <https://temporal.io/>.


## Getting Started

*NOTE: Make sure you have both Cadence and TChannel Proxy up and running. Head over to
*NOTE: Make sure you have both Temporal and TChannel Proxy up and running. Head over to
[this section](#installing-dependencies) for installation instructions.*

Clone this repository:

```sh
> git clone [email protected]:coinbase/cadence-ruby.git
> git clone [email protected]:coinbase/temporal-ruby.git
```

Include this gem to your `Gemfile`:

```ruby
gem 'cadence-ruby', path: 'path/to/a/cloned/cadence-ruby/'
gem 'temporal-ruby', path: 'path/to/a/cloned/temporal-ruby/'
```

Define an activity:

```ruby
class HelloActivity < Cadence::Workflow
class HelloActivity < Temporal::Workflow
def execute(name)
puts "Hello #{name}!"

Expand All @@ -41,7 +41,7 @@ Define a workflow:
```ruby
require 'path/to/hello_activity'

class HelloWorldWorkflow < Cadence::Workflow
class HelloWorldWorkflow < Temporal::Workflow
def execute
HelloActivity.execute!('World')

Expand All @@ -50,29 +50,29 @@ class HelloWorldWorkflow < Cadence::Workflow
end
```

Configure your Cadence connection:
Configure your Temporal connection:

```ruby
Cadence.configure do |config|
Temporal.configure do |config|
config.host = 'localhost'
config.port = 6666 # this should point to the tchannel proxy
config.domain = 'ruby-samples'
config.task_list = 'hello-world'
end
```

Register domain with the Cadence service:
Register domain with the Temporal service:

```ruby
Cadence.register_domain('ruby-samples', 'A safe space for playing with Cadence Ruby')
Temporal.register_domain('ruby-samples', 'A safe space for playing with Temporal Ruby')
```

Configure and start your worker process:

```ruby
require 'cadence/worker'
require 'temporal/worker'

worker = Cadence::Worker.new
worker = Temporal::Worker.new
worker.register_workflow(HelloWorldWorkflow)
worker.register_activity(HelloActivity)
worker.start
Expand All @@ -83,7 +83,7 @@ And finally start your workflow:
```ruby
require 'path/to/hello_world_workflow'

Cadence.start_workflow(HelloWorldWorkflow)
Temporal.start_workflow(HelloWorldWorkflow)
```

Congratulation you've just created and executed a distributed workflow!
Expand All @@ -97,25 +97,25 @@ available, make sure to check them out.

## Installing dependencies

In order to run your Ruby workers you need to have the Cadence service and the TChannel Proxy
In order to run your Ruby workers you need to have the Temporal service and the TChannel Proxy
running. Below are the instructions on setting these up:

### Cadence
### Temporal

Cadence service handles all the persistence, fault tolerance and coordination of your workflows and
Temporal service handles all the persistence, fault tolerance and coordination of your workflows and
activities. To set it up locally, download and boot the Docker Compose file from the official repo:

```sh
> curl -O https://raw.githubusercontent.com/uber/cadence/master/docker/docker-compose.yml
> curl -O https://raw.githubusercontent.com/temporalio/temporal/master/docker/docker-compose.yml

> docker-compose up
```

### TChannel Proxy

Right now the Cadence service only communicates with the workers using Thrift over TChannel.
Right now the Temporal service only communicates with the workers using Thrift over TChannel.
Unfortunately there isn't a working TChannel protocol implementation for Ruby, so in order to
connect to the Cadence service a simple proxy was created. You can run it using:
connect to the Temporal service a simple proxy was created. You can run it using:

```sh
> cd proxy
Expand All @@ -139,7 +139,7 @@ queries, etc) as it can break your workflows.*
Here's an example workflow:

```ruby
class RenewSubscriptionWorkflow < Cadence::Workflow
class RenewSubscriptionWorkflow < Temporal::Workflow
def execute(user_id)
subscription = FetchUserSubscriptionActivity.execute!(user_id)
subscription ||= CreateUserSubscriptionActivity.execute!(user_id)
Expand Down Expand Up @@ -199,8 +199,8 @@ An activity is a basic unit of work that performs the desired action (potentiall
side-effects). It can return a result or raise an error. It is defined like so:

```ruby
class CloseUserAccountActivity < Cadence::Activity
class UserNotFound < Cadence::ActivityException; end
class CloseUserAccountActivity < Temporal::Activity
class UserNotFound < Temporal::ActivityException; end

def execute(user_id)
user = User.find_by(id: user_id)
Expand All @@ -217,7 +217,7 @@ class CloseUserAccountActivity < Cadence::Activity
end
```

It is important to make your activities **idempotent**, because they can get retried by Cadence (in
It is important to make your activities **idempotent**, because they can get retried by Temporal (in
case a timeout is reached or your activity has thrown an error). You normally want to avoid
generating additional side effects during subsequent activity execution.

Expand All @@ -235,7 +235,7 @@ external event to complete your activity (e.g. a callback or a webhook). This ca
manually completing your activity using a provided `async_token` from activity's context:

```ruby
class AsyncActivity < Cadence::Activity
class AsyncActivity < Temporal::Activity
def execute(user_id)
user = User.find_by(id: user_id)

Expand All @@ -251,13 +251,13 @@ Later when a confirmation is received you'll need to complete your activity manu
provided:

```ruby
Cadence.complete_activity(async_token, result)
Temporal.complete_activity(async_token, result)
```

Similarly you can fail the activity by calling:

```ruby
Cadence.fail_activity(async_token, MyError.new('Something went wrong'))
Temporal.fail_activity(async_token, MyError.new('Something went wrong'))
```

This doesn't change the behaviour from the workflow's perspective — as any other activity the result
Expand All @@ -277,13 +277,13 @@ from your workflow

## Worker

Worker is a process that communicates with the Cadence server and manages Workflow and Activity
Worker is a process that communicates with the Temporal server and manages Workflow and Activity
execution. To start a worker:

```ruby
require 'cadence/worker'
require 'temporal/worker'

worker = Cadence::Worker.new
worker = Temporal::Worker.new
worker.register_workflow(HelloWorldWorkflow)
worker.register_activity(SomeActivity)
worker.register_activity(SomeOtherActivity)
Expand All @@ -297,22 +297,22 @@ worker you can split processing across as many workers as you need.

## Starting a workflow

All communication is handled via Cadence service, so in order to start a workflow you need to send a
message to Cadence:
All communication is handled via Temporal service, so in order to start a workflow you need to send a
message to Temporal:

```ruby
Cadence.start_workflow(HelloWorldWorkflow)
Temporal.start_workflow(HelloWorldWorkflow)
```

Optionally you can pass input and other options to the workflow:

```ruby
Cadence.start_workflow(RenewSubscriptionWorkflow, user_id, options: { workflow_id: user_id })
Temporal.start_workflow(RenewSubscriptionWorkflow, user_id, options: { workflow_id: user_id })
```

Passing in a `workflow_id` allows you to prevent concurrent execution of a workflow — a subsequent
call with the same `workflow_id` will always get rejected while it is still running, raising
`CadenceThrift::WorkflowExecutionAlreadyStartedError`. You can adjust the behaviour for finished
`TemporalThrift::WorkflowExecutionAlreadyStartedError`. You can adjust the behaviour for finished
workflows by supplying the `workflow_id_reuse_policy:` argument with one of these options:

- `:allow_failed` will allow re-running workflows that have failed (terminated, cancelled, timed out or failed)
Expand All @@ -328,7 +328,7 @@ of precedence):

1. Inline when starting or registering a workflow/activity (use `options:` argument)
2. In your workflow/activity class definitions by calling a class method (e.g. `domain 'my-domain'`)
3. Globally, when configuring your Cadence library via `Cadence.configure`
3. Globally, when configuring your Temporal library via `Temporal.configure`


## Breaking Changes
Expand All @@ -348,7 +348,7 @@ shipping the new release. It is also consistent for all the subsequent calls wit
`release_name` — all of them will return the original result. Consider the following example:

```ruby
class MyWorkflow < Cadence::Workflow
class MyWorkflow < Temporal::Workflow
def execute
ActivityOld1.execute!

Expand All @@ -364,7 +364,7 @@ end
which got updated to:

```ruby
class MyWorkflow < Cadence::Workflow
class MyWorkflow < Temporal::Workflow
def execute
Activity1.execute!

Expand Down Expand Up @@ -406,30 +406,30 @@ It is crucial to properly test your workflows and activities before running them
provided testing framework is still limited in functionality, but will allow you to test basic
use-cases.

The testing framework is not required automatically when you require `cadence-ruby`, so you have to
The testing framework is not required automatically when you require `temporal-ruby`, so you have to
do this yourself (it is strongly recommended to only include this in your test environment,
`spec_helper.rb` or similar):

```ruby
require 'cadence/testing'
require 'temporal/testing'
```

This will allow you to execute workflows locally by running `HelloWorldWorkflow.execute_locally`.
Any arguments provided will forwarded to your `#execute` method.

In case of a higher level end-to-end integration specs, where you need to execute a Cadence workflow
In case of a higher level end-to-end integration specs, where you need to execute a Temporal workflow
as part of your code, you can enable local testing:

```ruby
Cadence::Testing.local!
Temporal::Testing.local!
```

This will treat every `Cadence.start_workflow` call as local and perform your workflows inline. It
This will treat every `Temporal.start_workflow` call as local and perform your workflows inline. It
also works with a block, restoring the original mode back after the execution:

```ruby
Cadence::Testing.local! do
Cadence.start_workflow(HelloWorldWorkflow)
Temporal::Testing.local! do
Temporal.start_workflow(HelloWorldWorkflow)
end
```

Expand Down
Binary file removed assets/cadence_logo.png
Binary file not shown.
Binary file removed assets/cadence_logo_2.png
Binary file not shown.
Binary file added assets/temporal_logo.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion examples/Gemfile
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
source 'https://rubygems.org'

gem 'cadence-ruby', path: '../'
gem 'temporal-ruby', path: '../'

gem 'rspec', group: :test
6 changes: 3 additions & 3 deletions examples/README.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
# Ruby Cadence Examples
# Ruby Temporal Examples

This directory contains examples demonstraiting different features or this library and Cadence.
This directory contains examples demonstraiting different features or this library and Temporal.

To try these out you need to have Cadence and TChannel Proxy running ([setup instructions](https://github.com/coinbase/cadence-ruby#installing-dependencies)).
To try these out you need to have Temporal and TChannel Proxy running ([setup instructions](https://github.com/coinbase/temporal-ruby#installing-dependencies)).

Install all the gem dependencies by running:

Expand Down
2 changes: 1 addition & 1 deletion examples/activities/async_activity.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
class AsyncActivity < Cadence::Activity
class AsyncActivity < Temporal::Activity
timeouts start_to_close: 120

def execute
Expand Down
2 changes: 1 addition & 1 deletion examples/activities/echo_activity.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
class EchoActivity < Cadence::Activity
class EchoActivity < Temporal::Activity
def execute(text)
p "ECHO: #{text}"
end
Expand Down
8 changes: 4 additions & 4 deletions examples/activities/generate_file_activity.rb
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
require 'cadence/concerns/typed'
require 'temporal/concerns/typed'

class GenerateFileActivity < Cadence::Activity
include Cadence::Concerns::Typed
class GenerateFileActivity < Temporal::Activity
include Temporal::Concerns::Typed

task_list 'file-processing'

input Cadence::Types::String
input Temporal::Types::String

def execute(input)
file_name = "#{Time.now.to_i}.txt"
Expand Down
2 changes: 1 addition & 1 deletion examples/activities/hello_world_activity.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
class HelloWorldActivity < Cadence::Activity
class HelloWorldActivity < Temporal::Activity
def execute(name)
p "Hello World, #{name}"

Expand Down
4 changes: 2 additions & 2 deletions examples/activities/long_running_activity.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
class LongRunningActivity < Cadence::Activity
class Canceled < Cadence::ActivityException; end
class LongRunningActivity < Temporal::Activity
class Canceled < Temporal::ActivityException; end

def execute(cycles, interval)
cycles.times do
Expand Down
8 changes: 4 additions & 4 deletions examples/activities/process_file_activity.rb
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
require 'cadence/concerns/typed'
require 'temporal/concerns/typed'

class ProcessFileActivity < Cadence::Activity
include Cadence::Concerns::Typed
class ProcessFileActivity < Temporal::Activity
include Temporal::Concerns::Typed

task_list 'file-processing'

input Cadence::Types::String
input Temporal::Types::String

def execute(input)
file_contents = File.read(input)
Expand Down
10 changes: 5 additions & 5 deletions examples/activities/random_number_activity.rb
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
require 'cadence/concerns/typed'
require 'temporal/concerns/typed'

class RandomNumberActivity < Cadence::Activity
include Cadence::Concerns::Typed
class RandomNumberActivity < Temporal::Activity
include Temporal::Concerns::Typed

input do
attribute :min, Cadence::Types::Integer.default(0)
attribute :max, Cadence::Types::Integer
attribute :min, Temporal::Types::Integer.default(0)
attribute :max, Temporal::Types::Integer
end

def execute(input)
Expand Down
6 changes: 3 additions & 3 deletions examples/activities/randomly_failing_activity.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
class RandomlyFailingActivity < Cadence::Activity
class WrongGuess < Cadence::ActivityException; end
class TerminalGuess < Cadence::ActivityException; end
class RandomlyFailingActivity < Temporal::Activity
class WrongGuess < Temporal::ActivityException; end
class TerminalGuess < Temporal::ActivityException; end

retry_policy(
interval: 1,
Expand Down
Loading

0 comments on commit 34c02f6

Please sign in to comment.