Temporal Blog 09月30日 19:17
Temporal SDK开发:挑战与Rust核心方案
index_new5.html
../../../zaker_core/zaker_tpl_static/wap/tpl_guoji1.html

 

Temporal的SDK团队正致力于支持更多编程语言,并在此过程中面临独特挑战。SDK不仅是薄薄的API封装,还需要处理分布式系统中不同时间、不同参与者产生的事件及其状态变化。为了避免重复开发复杂逻辑,同时为用户提供符合各语言习惯的接口,Temporal决定构建一个共享的Rust核心SDK。Rust因其“无畏并发”、“高性能与安全”以及易于与其他语言集成的特性,成为理想选择。新的SDK将基于此Rust核心,确保可靠性和高性能,并有望支持更多语言,如即将发布的Node.js SDK。

🛠️ **SDK的复杂性与挑战**: Temporal的客户端SDK并非简单的网络请求封装,而是需要处理事件的协调和状态变更,这些可能在分布式系统中不同时间由不同组件产生。同时,SDK需支持多种语言,提供符合各语言习惯的接口,并保证长生命周期Worker的极端可靠性。

⚙️ **核心SDK的必要性**: 为了避免在每种语言的SDK中重复实现复杂的事件处理和状态机逻辑,Temporal决定开发一个共享的、用Rust编写的核心SDK。这个核心能够被不同语言的SDK调用,大幅提高开发效率和可维护性,同时降低对最终用户的操作负担。

🦀 **选择Rust的原因**: Rust凭借其“无畏并发”、“高性能与安全性”、强大的类型系统以及易于与C语言互操作的特性,成为构建核心SDK的理想选择。它满足了高性能、可维护性和跨语言集成的需求,且可以编译为WASM,为未来解锁更多可能性。

🚀 **未来发展与展望**: 基于Rust核心SDK的策略将加速新语言SDK的开发,并提升现有SDK的质量。Temporal计划首先推出基于Rust核心的Node.js SDK,并将其Go SDK迁移至此。长远来看,这将为Temporal生态系统带来更广泛的语言支持和更可靠的服务。

Perhaps you've heard that here at Temporal, we're working on new SDKs to support more languages. We are engineers on the SDK team and wanted to elaborate on our challenges and how we're meeting them.

Temporal faces some unique challenges with respect to our client side libraries, namely:

    The client side logic isn't just a thin wrapper over some HTTP/gRPC/etc calls. The SDK needs to handle the reconciliation of events and their related state changes, which may be generated at different times by different actors in the distributed system that is a Temporal deployment. More on this below. We want to support as many languages as possible, while avoiding duplicating the complex logic in each language. On top of that, we need to present an idiomatic-to-their-language interface to our users. We expect instances of the SDK (workflow and activity workers) to often be long lived, and hence the SDK must be extremely reliable.

In this post, we'll dive into the points mentioned above. We will also explain why we chose to write the Core SDK in Rust to help meet these goals. Note that some familiarity with Temporal's programming model will be helpful. Read more here. A Temporal SDK provides the APIs in your language of choice needed to author Workflows and Activities, as well as the behind-the-scenes logic required to drive them. They allow you to write durable, long lived business logic without worrying about burdensome retries or other temporary failure concerns. This is all done in a way that feels natural to your language of choice.

What's complex about it?#

From a 10,000 foot view, a Temporal worker follows this algorithm when running a workflow:

    Long poll the server for workflow tasks (for example, Server says "I need you to run the user's workflow code"). Apply the event history contained in the task to a collection of state machines associated with the workflow. Run the user's workflow code, appropriately providing values from history for the results of Activities, firing Timers and Signals, etc., until the workflow code eventually blocks on something that isn't in history yet, or exits the workflow function. Reply to the server, possibly telling it about some new commands (the things we blocked on, for example: "I want to start this timer") that have been generated by the user's code. Otherwise, notify that the workflow is completed. goto 1

As you might imagine, steps 2 and 3 are pretty complex, especially step 2. This complexity arises from the huge number of combinations of actions that need to be taken as a result of workflow history being fed into these state machines. In turn, they determine what happens in the user's workflow code, and what needs to be sent to the server.

The state machine for timers, for example, encodes the logic that determines when we tell the server that it needs to track a new timer or when one should be cancelled. It also determines if a timer should be blocked or not in the user's workflow code. It's one of the simplest machines, and there are about 16 of them we need to implement.

What may not be immediately clear is there's nothing language-specific about these state machines. Conceptually, they translate actions taken in your workflow code to commands that must be sent to the Temporal server. In the other direction, they translate workflow history into new information exposed to your workflow. This "translation" is the same regardless of what language your workflow is written in. In fact, there's no reason why semantically identical workflows written in different languages running on different workers couldn't handle each other's histories - though you probably wouldn't want to do this.

Yet, as it stands, each of our existing SDKs re-implement this difficult logic. Clearly, we don't want to repeat this for each language. We need some kind of Core SDK that all other language SDKs can be built upon.

Towards a shared core#

It's clear we could substantially accelerate the development of new SDKs and increase the maintainability of existing ones by building a shared common core library used by the language-specific SDKs.

We knew any design would need to meet the following requirements:

    Clean integration with other languages Good ergonomics for the end user (avoid imposing new operational requirements) High performance Maintainable

Those requirements are pretty restrictive. To expand on the operational requirements: it's desirable from a packaging and performance perspective to be able to live in the same process as the language-specific SDK. For an end user that means they can simply deploy one binary which will run their worker, rather than needing to deploy the core SDK separately.

To implement the core and meet the requirements, we need a. We need a hero to rise to the challenge! Enter... Rust.

Why Rust?#

There's a lot of good reasons to pick Rust; some of which could fill up entire separate blog posts. The same reasons it's gaining in popularity so quickly these days apply to why we chose it. "Fearless concurrency", "performance and safety", a quality type system, etc. These reasons check the "high performance" and "maintainable" boxes.

When it comes to connecting multiple languages to a shared library, the traditional choice is often C, but Rust makes for a safer and more modern alternative. Having language SDKs directly link to the Rust core meets our end-user-ease goal and keeps overhead low. There are other ways we could've tackled the problem (for example by running another process that communicates with the language-specific SDK over some kind of IPC), but those options probably fail our ease-of-use goal. If desirable, we can always run out-of-process later because we use Protobufs to represent data passed between the Core and language-specific SDKs. This technique also reduces the amount of duplicate code we would have to write for each new language.

Rust also very easily compiles to WASM, which unlocks some very interesting possibilities for us that we'll likely discuss in a future blog post.

There's one other reason that matters a lot to me personally: Rust is fun to write. It's not often (though certainly has been) said, but I think it's a huge part of the reason the language has grown in popularity so quickly. It presents a challenging but rewarding mental model that, once internalized, provides some deeply rewarding "a-ha!" moments while also bolstering you with that "if it compiles, it probably works" confidence.

What's next?#

In the future, we plan to support a larger selection of languages than we do currently, all based on top of the common core. We can expect Core to ensure a stable, well-tested basis for new languages SDKs where they all can benefit from the reliability and performance it provides.

Keep your eyes peeled for the first alpha release of our Node.js SDK which will be coming quite soon. It is built on top of the Rust core that we've been developing in tandem. We'll announce that release here on the blog as well as other communication channels.

Lastly, we plan to port our existing Go SDK to it as well. We're excited to grow the number of languages supported by Temporal, and bring you rock-solid reliability while doing it!

Fish AI Reader

Fish AI Reader

AI辅助创作,多种专业模板,深度分析,高质量内容生成。从观点提取到深度思考,FishAI为您提供全方位的创作支持。新版本引入自定义参数,让您的创作更加个性化和精准。

FishAI

FishAI

鱼阅,AI 时代的下一个智能信息助手,助你摆脱信息焦虑

联系邮箱 441953276@qq.com

相关标签

Temporal SDK开发 Rust 分布式系统 核心库 编程语言 并发 性能 可维护性
相关文章