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

Improve api response times by doing send_activity asynchronously #3493

Merged
merged 11 commits into from
Jul 10, 2023

Conversation

phiresky
Copy link
Collaborator

@phiresky phiresky commented Jul 5, 2023

Right now, all API responses (esp. create comment, like, etc) wait for send_activity to complete before returning to the caller. The API response though is already known before this, so it makes sense to do it afterwards, whenever the scheduler has time. send_activity can be very expensive because it has to collect all the interested parties, fetch more rows from db, insert a row into activities, parse a pem private key, and loop through all inboxes in order to schedule the outgoing tasks.

This does change the semantics a bit because errors in send_activity will not propagate to the HTTP caller. I'm not sure if this is required somewhere though. It's kind of not great anyways though, since if send_activity fails, it will be shown to the user as a failed action even though ::perform() succeded and returned a response (that is lost in the current version).

This does not decrease the total load, but it should increase responsiveness. It also requires one clone on responses, but most responses seem to be tiny.

@Nutomic
Copy link
Member

Nutomic commented Jul 6, 2023

Its a good idea. Unfortunately it breaks federation tests (api_tests/run-federation-test.sh) because those rely on the blocking behaviour to know when the federation actions are completed. Maybe the tokio::spawn could be used only in prod builds but not in debug to fix this.

On a side note, we also need to get rid of the SendActivity and Perform traits. The latter were only necessary for websocket. Then we can switch to normal actix-web handler methods which are much more flexible. But so far I couldnt think of a good way to do that, because api methods need to call apub send methods which are in an independent, parallel crate. Maybe some kind of message queue would work, although it seems wrong to use a message queue inside another.

Btw you can also move the webmention send to a background thread along with this.

@dessalines
Copy link
Member

Why not just move the apub sends into the API functions? That's more explicit anyway.

@dessalines
Copy link
Member

Its a good idea. Unfortunately it breaks federation tests (api_tests/run-federation-test.sh) because those rely on the blocking behaviour to know when the federation actions are completed. Maybe the tokio::spawn could be used only in prod builds but not in debug to fix this.

Could probably be fixed by a wait / sleep in the api test code.

@phiresky
Copy link
Collaborator Author

phiresky commented Jul 6, 2023

Why not just move the apub sends into the API functions? That's more explicit anyway.

Sorry, i don't understand exactly what you mean? You mean get rid of the SendActivity trait and move the content of send_activity into what's currently the Perform impls?

@dessalines
Copy link
Member

dessalines commented Jul 6, 2023

You mean get rid of the SendActivity trait and move the content of send_activity into what's currently the Perform impls?

Yep. SendActivity::send_activity(&data, &res, &apub_data).await?; could be moved inside the HTTP calls. (especially since not all calls send activities anyway) Then we could get rid of both of those traits. That's for @Nutomic to decide how to restructure tho.

@phiresky
Copy link
Collaborator Author

phiresky commented Jul 6, 2023

ok well makes sense, but i think it should maybe be a different PR? seems somewhat orthogonal

@Nutomic
Copy link
Member

Nutomic commented Jul 6, 2023

Why not just move the apub sends into the API functions? That's more explicit anyway.

Apub and api crates are currently completely independent, meaning code in api crates cant access any code in the apub crate. This means that both crates can be compiled in parallel which speeds up the build considerably.

Could probably be fixed by a wait / sleep in the api test code.

I would hate to do this because its much more fragile and slower.

@phiresky
Copy link
Collaborator Author

phiresky commented Jul 6, 2023

I'm looking for a clean way to fix the fed tests but I'm not sure. should i:

  • add a fixed delay of 2s to all the tests
  • loop fetching the data with an increasing delay with a loop that waits until a max time to see if the data was federated
  • add an API parameter to all post calls to wait for federation
  • add a environment variable to wait for federation
  • always wait for federation in debug mode

Edit: I'll solve it by adding a env var LEMMY_SYNCHRONOUS_FEDERATION that defaults to cfg!(debug_assertions).

@phiresky
Copy link
Collaborator Author

phiresky commented Jul 6, 2023

I've fixed the tests hopefully. No idea why CI just suddenly seems to cancel now.

@Nutomic Nutomic merged commit b35757b into LemmyNet:main Jul 10, 2023
1 check passed
@Nutomic
Copy link
Member

Nutomic commented Jul 10, 2023

Looks good, thanks!

dessalines added a commit that referenced this pull request Jul 10, 2023
* do send_activity after http response

* move to util function

* format

* fix prometheus

* make synchronous federation configurable

* cargo fmt

* empty

* empty

---------

Co-authored-by: Dessalines <dessalines@users.noreply.github.com>
PawanHegde pushed a commit to PawanHegde/lemmy that referenced this pull request Jul 10, 2023
…myNet#3493)

* do send_activity after http response

* move to util function

* format

* fix prometheus

* make synchronous federation configurable

* cargo fmt

* empty

* empty

---------

Co-authored-by: Dessalines <dessalines@users.noreply.github.com>
Nutomic added a commit that referenced this pull request Jul 10, 2023
* Fix #3366: API does return plain HTML errors

* Fix Clippy errors

* Improve api response times by doing send_activity asynchronously (#3493)

* do send_activity after http response

* move to util function

* format

* fix prometheus

* make synchronous federation configurable

* cargo fmt

* empty

* empty

---------

Co-authored-by: Dessalines <dessalines@users.noreply.github.com>

* Updating `login.rs` with generic `incorrect_login` response. (#3549)

* Adding v0.18.1 and v0.18.0 release notes. (#3530)

* Update RELEASES.md (#3556)

added instruction to find the location of your docker directory (especially useful for those who used ansible since they never had to setup docker manually)

* Use async email sender (#3554)

* Upgrade all dependencies (#3526)

* Upgrade all dependencies

* as base64

* Adding phiresky to codeowners. (#3576)

* Error enum fixed (#3487)

* Create error type enum

* Replace magic string slices with LemmyErrorTypes

* Remove unused enum

* Add rename snake case to error enum

* Rename functions

* clippy

* Fix merge errors

* Serialize in PascalCase instead of snake_case

* Revert src/lib

* Add serialization tests

* Update translations

* Fix compilation error in test

* Fix another compilation error

* Add code for generating typescript types

* Various fixes to avoid breaking api

* impl From<LemmyErrorType> for LemmyError

* with_lemmy_type

* trigger ci

---------

Co-authored-by: SleeplessOne1917 <abias1122@gmail.com>

* Only update site_aggregates for local site (#3516)

* Fix #3501 - Fix aggregation counts for elements removed and deleted (#3543)

Two bugs were found and fixed:
- previously elements removal and deletion were counted as two separate disappearances
- removing comments did not affect post aggregations

* Use LemmyErrorType also make error_type compulsory

* Add missing import for jsonify_plain_text_errors

* Fix formatting

* Trying to make woodpecker run again

---------

Co-authored-by: phiresky <phireskyde+git@gmail.com>
Co-authored-by: Dessalines <dessalines@users.noreply.github.com>
Co-authored-by: rosenjcb <rosenjcb@gmail.com>
Co-authored-by: nixoye <12674582+nixoye@users.noreply.github.com>
Co-authored-by: dullbananas <dull.bananas0@gmail.com>
Co-authored-by: Nutomic <me@nutomic.com>
Co-authored-by: SleeplessOne1917 <abias1122@gmail.com>
Co-authored-by: Sander Saarend <sander@saarend.com>
Co-authored-by: Piotr Juszczyk <74842304+pijuszczyk@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants