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

Asynchronous uploads (MSC2246) #364

Closed
wants to merge 6 commits into from

Conversation

hifi
Copy link

@hifi hifi commented Mar 18, 2022

Initial implementation of MSC2246 after it was simplified.

With Redis signaling it's also possible to run matrix-media-repo behind a load balancer and get notified of finished uploads across processes.

Gated and prefixed as unstable as per the MSC.

Expands async upload notify support to multiple processes.

The logic is all instances of media repo subscribe to all shards
for upload notify events and any instance published an event to
one of them. This could be done in reverse as well but I found this
somewhat easier to do.
hifi and others added 3 commits March 21, 2022 21:32
upload: handle as PUT request

According to
matrix-org/matrix-spec-proposals#2246, the new
upload endpoint is a PUT endpoint, not a POST.
Copy link
Member

@turt2live turt2live left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

generally this seems fine - thanks for taking a look! I haven't checked it against the MSC yet, but more interested in ensuring it works within a context of the project structure first.

@@ -97,3 +130,21 @@ func (c *RedisCache) GetBytes(ctx rcontext.RequestContext, key string) ([]byte,
b, err := r.Bytes()
return b, err
}

func (c *RedisCache) NotifyUpload(ctx rcontext.RequestContext, origin string, mediaId string) error {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removing the redis notifications would be good, as it's not currently safe to be running the media repo as multiple processes. The approach for this is expected to look a bit different architecturally in the end.

@@ -59,12 +100,16 @@ func UploadMedia(r *http.Request, rctx rcontext.RequestContext, user api.UserInf

contentLength := upload_controller.EstimateContentLength(r.ContentLength, r.Header.Get("Content-Length"))

media, err := upload_controller.UploadMedia(r.Body, contentLength, contentType, filename, user.UserId, r.Host, rctx)
media, err := upload_controller.UploadMedia(r.Body, contentLength, contentType, filename, user.UserId, r.Host, mediaId, rctx)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

StoreDirect should probably be used instead of UploadMedia when the media ID is known, similar to an import. Though, the upload size check might need to be moved up to somewhere. Possibly a new function which calls StoreDirect but is named OverwriteExisting or something?

UnusedExpiresAt int64 `json:"unused_expires_at"`
}

func CreateMedia(r *http.Request, rctx rcontext.RequestContext, user api.UserInfo) interface{} {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This isn't r0, so should be in the unstable directory instead (alongside the media info and local copy endpoints).

@@ -48,21 +48,38 @@ func DownloadMedia(r *http.Request, rctx rcontext.RequestContext, user api.UserI
downloadRemote = parsedFlag
}

var asyncWaitMs *int = nil
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ideally this is a non-pointer int throughout, for code clarity more than anything. A wait time of zero is still semantically possible.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Having it as a nillable pointer was to make it distinct it's not set vs it being set to zero. Not setting it from the request makes the code pick up the default from the configuration file.

@turt2live
Copy link
Member

Thanks again for the PR! I've been working on what is best described as a rewrite of the whole project and added MSC2246 support as a first-class citizen. That progress is tracked here: #407

It's a bit different from how you've implemented it here, but should have the same functionality.

@turt2live turt2live closed this Jun 11, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants