Skip to content

feat: use one transaction per move item and send ws after the transaction#835

Open
ReidyT wants to merge 6 commits intomainfrom
831-send-ws-feedback-after-transaction-move
Open

feat: use one transaction per move item and send ws after the transaction#835
ReidyT wants to merge 6 commits intomainfrom
831-send-ws-feedback-after-transaction-move

Conversation

@ReidyT
Copy link
Contributor

@ReidyT ReidyT commented Feb 21, 2024

  • use one transaction for each move item
  • publish websocket post move item after the transaction
  • publish websocket feedback after all the transactions

For more details, please see #831

Validation of the Implementation

Protocol of the Test:

  • Run each test five times to obtain an average time.
  • The time is computed as the highest end time minus the smallest start time.
    • This is because the maximum number of moves is 20, so to move 100 items, it will require 5 API calls.
  • For each test, the items and actions are reset.
    • There are 100 items, each with 10 children => 1000 items.
    • There are 1000 actions per item => 1,000,000 actions.
  • For each test with web sockets, the builder is forced to refresh.

Tests 1 - Parallel vs Series with Multiple Transactions without Intermediate Web Sockets

In Series In Parallel
Time 1 (ms) 26,916 33,155
Time 2 (ms) 24,872 27,055
Time 3 (ms) 30,011 35,195
Time 4 (ms) 28,483 25,567
Time 5 (ms) 29,027 34,580
Avg. Time (ms) 27,862 31,110

Results: Parallel seems to be slower than in series. Also, in series, the feedback isn’t sent at the end of the 20 items but at the whole end.

Important

In parallel, each promise has its own thread freezing the database for the time that the move is run. This is not acceptable.

Note

Maybe use a thread pool (running 5 threads, in each thread having 20 items to move in series…)

Test 2 - Only One Transaction, moving items are executed in parallel, without web sockets

In Parallel
Time 1 (ms) 27,455
Time 2 (ms) 27,808
Time 3 (ms) 26,761
Time 4 (ms) 33,306
Time 5 (ms) 30,993
Avg. Time (ms) 29,265

Test 3 - Parallel vs Series with Multiple Transactions and web sockets

Important

Refresh the browser to be sure to have a web socket connection!!!

The problem principally comes from the rerender of the table… Indeed, when disabling the invalidation, the manual manipulations conduct to a re-render, involving the HTTP Requests.

In Series In Parallel
Time 1 (ms) 71,963 54,972
Time 2 (ms) 64,392 79,857
Time 3 (ms) 75,210 74,077
Time 4 (ms) 68,794 40,444
Time 5 (ms) 63,661 51,855
Avg. Time (ms) 68,804 60,241

Results: In parallel is a little bit faster.

- move transaction into move function of itemService
- publish websocket post move item after the transaction
- publish websocket feedback after all the transactions
@ReidyT ReidyT self-assigned this Feb 21, 2024
- each transaction execute one move
- add ws services to publish websockets
@ReidyT ReidyT changed the title feat: move the transaction inside each move function feat: use one transaction per move item and send ws after the transaction Feb 23, 2024
- check that the move is committed when ws is received
@ReidyT ReidyT marked this pull request as ready for review February 23, 2024 08:43
@ReidyT ReidyT requested review from pyphilia and spaenleh February 23, 2024 08:43
Copy link
Contributor

@pyphilia pyphilia left a comment

Choose a reason for hiding this comment

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

Thanks for the PR! Here are some ideas to refactor the code, plus some questions 🐈

}
}).catch((e) => {
log.error(e);
Promise.allSettled<Item>(
Copy link
Contributor

Choose a reason for hiding this comment

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

Something that would be worth checking is whether all promises start at the same time, or if they are running one after the other. I think we prefer not sending them all at the same time. What do you think?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

According to the javascript documentation, The Promise class offers four static methods to facilitate async task [concurrency](https://en.wikipedia.org/wiki/Concurrent_computing), so it should be "in parallel".

They also indicates: Note that JavaScript is [single-threaded](https://developer.mozilla.org/en-US/docs/Glossary/Thread) by nature, so at a given instant, only one task will be executing, although control can shift between different promises, making execution of the promises appear concurrent.

So, maybe it is better to run in series as you mentioned here to be sure that there is no deadlock ?

Comment on lines -394 to -397
await this.hooks.runPreHooks('move', actor, repositories, {
source: item,
destinationParent: parentItem,
});
Copy link
Contributor

Choose a reason for hiding this comment

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

So there's no prehook anymore?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I didn't found one listening for move preHooks...

Comment on lines +100 to +113
errors: [],
},
),
);
}
if (failed.length) {
failed.forEach((e) => {
log.error(e);
websockets.publish(
memberItemsTopic,
memberId,
ItemOpFeedbackEvent('move', failedIds, { error: e }),
);
});
Copy link
Contributor

Choose a reason for hiding this comment

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

Why not having one feedback with the errors within the "success" message and let the frontend trigger the multiple notifications? I know we discussed it sorry..

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Because there are some changes to do... but I can actually do this now.

- implement ItemWebsocketsService class
- implement SeriesPromise class to run Promises in series
- use newly postMoveAction function
@sonarqubecloud
Copy link

sonarqubecloud bot commented Mar 1, 2024

Quality Gate Passed Quality Gate passed

Issues
10 New issues
0 Accepted issues

Measures
0 Security Hotspots
No data about Coverage
2.9% Duplication on New Code

See analysis details on SonarCloud

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.

Update the web socket of the move items to be sent after the transaction

2 participants