Elixir SDK Support In The Roadmap?

Hey All,

Just wondering if anyone knows of plans for an ELixir SDK? I see this: How much work is it to write an SDK? that hasn’t had any movement for some time.

Seems like the only language missing in this ectosystem, and I think it would be great to see elixir supoprted here. Additionally, I’m seeing other similar projects like inngest where they are taking a crack at elixir support.

I think the warning that this is likely a 6 month plus task maybe put a lot of people off just beginning this, is there any docs anywhere that might help with building out a bare bones api for this?

Also, there is already a protobuff generated elixir project here temporalio | Hex which looks like a good start.

Chris

I am finalizing work on the Erlang SDK (unofficial), initial release should be available in Sep-Oct. Elixir SDK as a wrapper on top of Erlang SDK is planned for Q4. All dates are tentative.

I would say that 6 months is a very optimistic schedule assumption for a full-feature Temporal SDK development, even if it would be based on a Core SDK.

1 Like

Great news, thanks for taking up the challenge. Let me know if you need anything to test things out in the future

1 Like

@andrzej-mag - This is very neat! Elixir/Erlang should fit Temporal’s workflow model well (maybe more than any other runtime). Feel free to ask any questions in the #sdk-core Slack channel, we’d be happy to clarify anything confusing about SDK internals.

1 Like

Hey @andrzej-mag did you make any progress in this endeavor?

If so, do you have a public GitHub repo to see the state of play?

One thought, while it’s amazing to have a fully fledged feature complete version, I think there’s a lot of value in just a partial solution.

For example just bring able to bundle up Erlang/elixir activities, with limited functionality, and have workflows defined in other languages may still be valuable.

Chris

Hi Chris,
Project is advancing steadily however it is not ready for publishing yet. Tentative project schedule was provided in my previous answer.

As you mentioned Temporal activities, quick preview of current WIP Erlang SDK activities API implementation:

-module(temporal_sdk_activity).

-export([
    await/0,
    await/1,
    cancel/1,
    complete/1,
    fail/3,
    heartbeat/0,

    is_cancel_requested/0,
    elapsed_time/0,
    remaining_time/0,

    get_data/0,
    get_failure_info/0,
    get_last_heartbeat/0,
    set_data/1,
    set_failure_info/1
]).

-include("temporal_sdk_proto.hrl").

-type task() :: ?TEMPORAL_SPEC:'temporal.api.workflowservice.v1.PollActivityTaskQueueResponse'().
-export_type([task/0]).

-type data() :: term().
-export_type([data/0]).

-type last_heartbeat() :: term().
-export_type([last_heartbeat/0]).

-type context() ::
    #{
        cluster := temporal_sdk_cluster:cluster_name(),
        executor_pid := pid(),
        otel_ctx := otel_ctx:t(),
        worker_opts := temporal_sdk_worker:opts(),
        task := task(),
        started_at := SystemTime :: integer(),
        is_cancel_requested := boolean(),
        task_timeout := erlang:timeout(),
        data := data(),
        last_heartbeat := last_heartbeat()
    }.
-export_type([context/0]).

-type fail_reason() :: {Message :: term(), Source :: term(), Stacktrace :: term()}.
-export_type([fail_reason/0]).

-type handle_event_result() :: term().
-export_type([handle_event_result/0]).

%% -------------------------------------------------------------------------------------------------
%% behaviour

-type cancel_action() :: {cancel, CanceledDetails :: temporal_sdk:term_to_payloads()}.
-type complete_action() :: {complete, Result :: temporal_sdk:term_to_payloads()}.
-type fail_action() ::
    {fail, Reason :: fail_reason()}
    | {fail, Reason :: fail_reason(), FailureInfo :: temporal_sdk_worker:failure_info()}.
-type terminate_action() :: cancel_action() | complete_action() | fail_action().
-type heartbeat_action() :: heartbeat | {heartbeat, Heartbeat :: temporal_sdk:term_to_payloads()}.

-callback execute(Context :: context(), Args :: temporal_sdk:term_from_payloads()) ->
    Result :: temporal_sdk:term_to_payloads().

-callback handle_heartbeat(Context :: context()) ->
    terminate_action() | heartbeat_action().

-callback handle_cancel(Context :: context()) ->
    terminate_action() | ignore.

-callback handle_call(Context :: context(), From :: gen_statem:from(), Request :: term()) ->
    handle_event_result() | ignore.

-callback handle_cast(Context :: context(), Request :: term()) ->
    handle_event_result() | ignore.

-callback handle_info(Context :: context(), Info :: term()) ->
    handle_event_result() | ignore.

-optional_callbacks([
    handle_heartbeat/1,
    handle_cancel/1,
    handle_call/3,
    handle_cast/2,
    handle_info/2
]).

%% -------------------------------------------------------------------------------------------------
%% public

-spec await() -> handle_event_result() | no_return().
await() ->
    await(infinity).

-spec await(Timeout :: erlang:timeout()) -> handle_event_result() | no_return() | timeout.
await(Timeout) ->
% implementation follows...
1 Like