Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add blog post for tusd v2 #395

Merged
merged 13 commits into from
Sep 29, 2023
65 changes: 65 additions & 0 deletions src/content/blog/2023-09-20-tusd-200.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
---
title: 'tusd v2: More interoperable and resilient'
Acconut marked this conversation as resolved.
Show resolved Hide resolved
author: acconut
redirect_from: /blog/2023/09/20/tusd-200/
date: 2023-09-20
---
Exactly fours years after the last major release of tusd, [version 1.0.0](https://tus.io/blog/2019/09/20/tusd-100), it is time for another big announcement: We are happy to say that tusd v2 is finished and ready for production!
Acconut marked this conversation as resolved.
Show resolved Hide resolved

This major release focuses on two main aspects: **interoperability and resilience**. The reworked hook system makes it easier to integrate tusd into your application, while also extending its functionality. Furthermore, we focused on how tusd handles degraded network connectivity and made numerous changes to improve its resilience in such circumstances. Besides these main aspects, there are additional improvements, which are all described in the following sections.

Before we talk about them in more details, I want to emphasize that there are **no breaking changes in the HTTP interface for tus uploads**. Existing tus clients will continue to be able to communicate with tusd without any changes being necessary. You can replace your tusd v1 deployments with v2 and all clients will continue to function.

## Hook system

This major release includes an entirely reworked hook system. Hooks enable bi-directional communication between the tus upload server and your main application. During the lifecycle of an upload, events are emitted that can notify your application whenever an upload is started, finished, or while data is being transmitted. This allows for a tight integration of resumable uploads into your system.

In the previous versions, this hook interface was mainly design for one-directional communication that flows from tusd to your main application. Over the time, we realized that this approach is too limited and developers want to also send feedback back to tusd in order to reject upload before they are created, send fully-customized error messages to the clients and include additional information in the responses once an upload is complete. tusd v1 did not have proper support for these tasks.

With tusd v2, we have completely reworked the hook system making it more powerful than before:

- Hooks can be sent to your application via HTTP, gRPC, by invoking scripts, or by loading plugins into tusd. Plugins are a new and efficient hook provider, where you can write callbacks using Go and load them into tusd.
- Hooks can fully customize every HTTP response that is sent from tusd to the tus clients. This includes the status code, header fields, and the response body for success and error cases.
Acconut marked this conversation as resolved.
Show resolved Hide resolved
- Hooks can reject an upload creation, for example if validation of the meta data fails or the user is not authorized.
- Hooks can stop ongoing uploads to avoid unnecessary resource consumption, for example if an underlying resource is no longer available.
- Hooks can customize the upload ID and its meta data when a new upload is created, influencing its storage destination.

You can read more about this in the [hook system documentation](https://github.com/tus/tusd/blob/main/docs/hooks.md). If you are already using hooks, upgrading to tusd v2 is simple. The structure of the hook information has changed slightly, but still provides all the data as before. We encourage you to have a look at the documentation and the corresponding [examples](https://github.com/tus/tusd/tree/main/examples)!
Acconut marked this conversation as resolved.
Show resolved Hide resolved

## Network resilience

Tusd must accept large uploads even over unreliable network connections and, thus, must be resilient to various kinds of network issues and interruptions. With tusd v2, we worked on improvements in this area as well:

A new **end-to-end** test suite has been developed that simulates various network conditions, such as slow upload speeds, dead connections, and concurrent requests. It allows us to observe tusd's behavior and asserts its correctness in as siutations. It has been central in our latest efforts to ensure that the tusd v2 release is ready for production.

One topic that has been especially tricky in the past are concurrent upload requests. tusd does not support concurrent requests to the same upload resource, as parallel writes could trigger data loss. This rule is enforced through locks, which must be acquired before accessing or modifying an upload. While it solves the problem of concurrent access, it creates another one: When an ongoing upload is interrupted by network issues, the server might be unaware of this interruption and assume that the upload is still continuing and thus holding onto the upload lock. The client, on the other hand, might realize this interruption and abandon the previous upload request to resume the upload. This resumption would fail because the upload is still locked from the previous request, until the connection times out. Depending on the setup, such a timeout can be lengthy and thus cause annoyances for the end-users.

As a solution, tusd v2 allows new requests to ask previous requests to the same upload resource to release their upload lock in a controlled and safe manner. This solves the problem of locked uploads during resumption, while also ensuring no data corruption. You can read more about the topic of upload locks in the [corresponding documentation](https://github.com/tus/tusd/blob/main/docs/locks.md).

## Further improvements
Acconut marked this conversation as resolved.
Show resolved Hide resolved

Besides an improved hook system and more resilience, tusd v2 also includes enhancements in the follow areas:

- **Parts are uploaded in parallel to AWS S3:** To implement S3-backed resumable upload, tusd splits an upload into multiple parts and transfers each part individually to S3 using its [multipart uploading functionality](https://docs.aws.amazon.com/AmazonS3/latest/userguide/mpuoverview.html). In tusd v2, the part transfers are now parallelized to achieve higher throughput for the end user.
- **Graceful shutdown:** Upon receiving a signal to shut down (i.e. SIGINT, SIGTERM or Ctrl+C), tusd will now attempt a graceful exit: First it stops accepting new connections before ending all open uploads while giving the storages enough time to save all buffered data. This reduces data loss and makes reloading tusd more efficient.
- **Online profiling support:** Powered by Go's [pprof package](https://pkg.go.dev/net/http/pprof), you can now profile the CPU and memory usage of tusd while it is running - even in production with little overhead! This can be enabled using the new `-expose-pprof` option.
- **Support for the new IETF protocol:** We are working with the HTTP working group of the IETF on a [new standard for resumable file uploads](/blog/2023/08/09/resumable-uploads-ietf). This release includes preliminary support for this experimental protocol via the `-enable-experimental-protocol` flag.
Acconut marked this conversation as resolved.
Show resolved Hide resolved
- **Updated dependencies:** As with every release, we upgraded all dependencies to their latest versions to ensure that we include all available stability and security fixes.

## Breaking Changes
Acconut marked this conversation as resolved.
Show resolved Hide resolved

Unfortunately, this release also brings some breaking changes along. Affected users are required to adjust their tusd installation, even though the necessary changes should be minimal.

- **Require Go 1.20:** Our upgrade policy dictates that we always support the last two major releases of Go. As of the release of tusd v2, this is Go 1.20 and 1.21. Earlier versions are not supported anymore. If you are building tusd on your own or are using it as a package, please ensure that you are using one of these versions.
- **For users of tusd as a CLI:**
- Flags that specify a duration have a new syntax: Before v2, their value was parsed as the number of milliseconds (e.g. `-duration=6000`). Now, the value is parsed as a number with an attached unit of time (e.g. `-duration=6s`).
- The `-timeout` flag has been renamed to `-network-timeout` to better describe its actual effect.
- As mentioned above, the structure of the data provided in hooks has slightly changed. Please consult the [hook system documentation](https://github.com/tus/tusd/blob/main/docs/hooks.md#hook-requests-and-responses) for the updated structure.
- **For users of tusd as a package:**
- The `Config.DisableCors` field has been removed in favor of the more complete [`Config.Cors` option](https://pkg.go.dev/github.com/tus/tusd/v2/pkg/handler#Config), which allows you to adjust all CORS-related aspects of your handler.
- The `s3store` has been upgraded to use the newer AWS SDK for Go v2. Please check the corresponding [migration guide](https://aws.github.io/aws-sdk-go-v2/docs/migrating/) to upgrade from the AWS SDK for Go v1.
- The data stores are now required to return an `io.ReadCloser` (instead of just an `io.Reader`) for `GetReader` calls when a client wants to download a file. The additional close functionality is used to better clean up resources.

That being said, tusd v2 does not introduce a breaking change for its HTTP interface. All current tus clients can be used without modifications with tusd v2. Tusd can be upgraded in production from v1 to v2 seamlessly without changes to the clients.

Finally, I want to thank all contributors, who dedicated their time and efforts towards this release! It would not be possible without you!
Acconut marked this conversation as resolved.
Show resolved Hide resolved
Loading