Skip to content
This repository has been archived by the owner on May 31, 2021. It is now read-only.

Multi rtorrent instances support #549

Merged
merged 11 commits into from
Mar 14, 2018
Merged

Multi rtorrent instances support #549

merged 11 commits into from
Mar 14, 2018

Conversation

zawapete
Copy link
Contributor

@zawapete zawapete commented Nov 25, 2017

Description

  • Added rtorrent scgi data on user signup
  • Lazy load user/instance db with multi session support
  • Add username to xml-rpc callback
  • Users data separation in services

Related Issue

#460 (comment)

Motivation and Context

See issue

How Has This Been Tested?

Tested on a server with three separated rtorrent instances on socket

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)

Once it works we could provide a migration script so that the change won't be breaking

Checklist:

  • My code follows the code style of this project.
  • My change requires a change to the documentation.
  • I have updated the documentation accordingly.
  • I have read the CONTRIBUTING document.
  • I have added tests to cover my changes.
  • All new and existing tests passed.

@zawapete zawapete changed the title WIP multi rtorrent instances support Multi rtorrent instances support Nov 26, 2017
@jfurrow
Copy link
Member

jfurrow commented Nov 28, 2017

I've only just started to review, but I must say I'm really impressed @zawapete. Thanks for this — it looks like you found a relatively simple way to tackle this daunting task.

I'll need some more time to think about this and review the code, but I think I'm mostly in favor of consuming multiple rtorrent instances, for most of the reasons stated in this comment. Maybe your PR already does this, but in the future, it would be great to support both multiple rtorrent instances and multiple users. This would pave the way for more advanced administration controls.

I really like the idea of configuring rtorrent in the UI, even for single-user instances. I've been thinking about this for a while — we could (and should) add error handling to improve the entire configuration experience.

@zawapete
Copy link
Contributor Author

@jfurrow you can setup different users to the same rtorrent instances, but the db will be separated. This means that data that has rtorrent instance as source are shared, but data that has db as source are isolated (like rss feed, that I presume it works now out of the box, but I haven't tested such scenario).
If we want to isolate data coming from rtorrent instance we should add them to the db layer, and that will come.

@jvacek
Copy link

jvacek commented Dec 5, 2017

Leaving socket empty or inputting "false" on initial user creation (localhost and 5001 for host and socket) causes the following
Connection refused at 127.0.0.1. Check these values in config.js and ensure that rTorrent is running. GET /api/client/settings 500 270.013 ms - 88

Registering a user without a socket throws the following error

POST /auth/register 200 58.948 ms - 208
net.js:970
      throw new RangeError('"port" option should be >= 0 and < 65536: ' + port);
      ^

RangeError: "port" option should be >= 0 and < 65536:
    at lookupAndConnect (net.js:970:13)
    at Socket.realConnect (net.js:945:5)
    at Object.connect (net.js:77:22)
    at /opt/flood-pull/server/util/scgi.js:40:26
    at db.findOne (/opt/flood-pull/server/models/Users.js:153:14)
    at newArguments.(anonymous function) (/opt/flood-pull/node_modules/nedb/lib/executor.js:29:17)
    at Cursor.execFn (/opt/flood-pull/node_modules/nedb/lib/datastore.js:518:14)
    at callback (/opt/flood-pull/node_modules/nedb/lib/cursor.js:126:19)
    at /opt/flood-pull/node_modules/nedb/lib/cursor.js:193:12
    at /opt/flood-pull/node_modules/nedb/lib/datastore.js:329:14

npm ERR! Linux 4.4.0-97-generic
npm ERR! argv "/usr/bin/nodejs" "/usr/bin/npm" "start"
npm ERR! node v4.2.6
npm ERR! npm  v3.5.2
npm ERR! code ELIFECYCLE
npm ERR! [email protected] start: `node server/bin/start.js`
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the [email protected] start script 'node server/bin/start.js'.
npm ERR! Make sure you have the latest version of node.js and npm installed.
npm ERR! If you do, this is most likely a problem with the flood package,
npm ERR! not with npm itself.
npm ERR! Tell the author that this fails on your system:
npm ERR!     node server/bin/start.js
npm ERR! You can get information on how to open an issue for this project with:
npm ERR!     npm bugs flood
npm ERR! Or if that isn't available, you can get their info via:
npm ERR!     npm owner ls flood
npm ERR! There is likely additional logging output above.

npm ERR! Please include the following file with any support request:
npm ERR!     /opt/flood-pull/npm-debug.log

and the npm debug contains the follwoing:

0 info it worked if it ends with ok
1 verbose cli [ '/usr/bin/nodejs', '/usr/bin/npm', 'start' ]
2 info using [email protected]
3 info using [email protected]
4 verbose run-script [ 'prestart', 'start', 'poststart' ]
5 info lifecycle [email protected]~prestart: [email protected]
6 silly lifecycle [email protected]~prestart: no script for prestart, continuing
7 info lifecycle [email protected]~start: [email protected]
8 verbose lifecycle [email protected]~start: unsafe-perm in lifecycle true
9 verbose lifecycle [email protected]~start: PATH: /usr/share/npm/bin/node-gyp-bin:/opt/flood-pull/node_modules/.bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/snap/bin
10 verbose lifecycle [email protected]~start: CWD: /opt/flood-pull
11 silly lifecycle [email protected]~start: Args: [ '-c', 'node server/bin/start.js' ]
12 silly lifecycle [email protected]~start: Returned: code: 1  signal: null
13 info lifecycle [email protected]~start: Failed to exec start script
14 verbose stack Error: [email protected] start: `node server/bin/start.js`
14 verbose stack Exit status 1
14 verbose stack     at EventEmitter.<anonymous> (/usr/share/npm/lib/utils/lifecycle.js:232:16)
14 verbose stack     at emitTwo (events.js:87:13)
14 verbose stack     at EventEmitter.emit (events.js:172:7)
14 verbose stack     at ChildProcess.<anonymous> (/usr/share/npm/lib/utils/spawn.js:24:14)
14 verbose stack     at emitTwo (events.js:87:13)
14 verbose stack     at ChildProcess.emit (events.js:172:7)
14 verbose stack     at maybeClose (internal/child_process.js:821:16)
14 verbose stack     at Process.ChildProcess._handle.onexit (internal/child_process.js:211:5)
15 verbose pkgid [email protected]
16 verbose cwd /opt/flood-pull
17 error Linux 4.4.0-97-generic
18 error argv "/usr/bin/nodejs" "/usr/bin/npm" "start"
19 error node v4.2.6
20 error npm  v3.5.2
21 error code ELIFECYCLE
22 error [email protected] start: `node server/bin/start.js`
22 error Exit status 1
23 error Failed at the [email protected] start script 'node server/bin/start.js'.
23 error Make sure you have the latest version of node.js and npm installed.
23 error If you do, this is most likely a problem with the flood package,
23 error not with npm itself.
23 error Tell the author that this fails on your system:
23 error     node server/bin/start.js
23 error You can get information on how to open an issue for this project with:
23 error     npm bugs flood
23 error Or if that isn't available, you can get their info via:
23 error     npm owner ls flood
23 error There is likely additional logging output above.
24 verbose exit [ 1, true ]

With that said, I didn't manage to run it but I'm super curious
I haven't gone that much further in working with rtorrent beyond getting it to run so I'm not sure if I'm just configuring it incorrectly but the current state for me does not seem to test and verify the configuration, or reject incorrect input. The app gets bricked unless you remove the db folder and start it fresh.

@zawapete
Copy link
Contributor Author

zawapete commented Dec 6, 2017

@jvacek I tested with socket, probably and input validation problem in saving host/port data. I will test and fix. can you attach the content of user.db? (at least the part for rtorrent connection data)

@jvacek
Copy link

jvacek commented Dec 6, 2017

@zawapete sorry I just realised my error, I was filling in both the port and the socket.
I would suggest changing the input for this method a little, possibly using a toggle between port and socket instead (or radio buttons) of a checkbox to show that it is one or the other that you should be filling in, and disable (or hide) the other field accordingly.

I now managed to connect to my instance fine, added a new user with a different port, everything seems to work as expected from my side.

One thing that would be preventing me from rolling this out for the time being is that the consecutive users can create more users. An admin/user distinction would be very useful. One case would be that the First created user is admin, all other ones are users by default, allow admin to give other users admin prvilleges.
Another is to make a matrix of access rights for different parts of the software which could be a lot more modular appoach (authentication, new user creation, changing ports/sockets, )
Would possibly also be super useful to prevent users from toying with their connectivity settings through this access

On the user experience side, except for the permissions and some UI tweaks, I give this A+, five stars and a diploma rating. Does what it should.

Here's a couple bugs I encountered while running this version of the pull. I'll keep updating the thread as I find more bugs, I'll try using this version fo flood concurrently with a couple of my users for a week or so.

This one occured to me when I was going through the settings, however that does not seem to be realted to this crash.

GET /auth/users 304 13.770 ms - -
GET /api/notifications?limit=10&start=0 304 3922.544 ms - -
GET /api/notifications?limit=10&start=0 304 1238.597 ms - -
GET /api/activity-stream?historySnapshot=fiveMin 200 102.546 ms - -
GET /api/notifications?limit=10&start=0 304 2808.722 ms - -
GET /api/activity-stream?historySnapshot=fiveMin 200 126.163 ms - -
GET /api/activity-stream?historySnapshot=fiveMin 200 15.590 ms - -
/opt/flood-pull/node_modules/nedb/lib/datastore.js:77
    if (err) { throw err; }
               ^

Error: ENOENT: no such file or directory, rename './server/db/vhtSHwaE1Iad9siM/notifications.db~' -> './server/db/vhtSHwaE1Iad9siM/notifications.db'

npm ERR! Linux 4.4.0-97-generic
npm ERR! argv "/usr/bin/nodejs" "/usr/bin/npm" "start"
npm ERR! node v4.2.6
npm ERR! npm  v3.5.2
npm ERR! code ELIFECYCLE
npm ERR! [email protected] start: `node server/bin/start.js`
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the [email protected] start script 'node server/bin/start.js'.
npm ERR! Make sure you have the latest version of node.js and npm installed.
npm ERR! If you do, this is most likely a problem with the flood package,
npm ERR! not with npm itself.
npm ERR! Tell the author that this fails on your system:
npm ERR!     node server/bin/start.js
npm ERR! You can get information on how to open an issue for this project with:
npm ERR!     npm bugs flood
npm ERR! Or if that isn't available, you can get their info via:
npm ERR!     npm owner ls flood
npm ERR! There is likely additional logging output above.

npm ERR! Please include the following file with any support request:
npm ERR!     /opt/flood-pull/npm-debug.log

0 info it worked if it ends with ok
1 verbose cli [ '/usr/bin/nodejs', '/usr/bin/npm', 'start' ]
2 info using [email protected]
3 info using [email protected]
4 verbose run-script [ 'prestart', 'start', 'poststart' ]
5 info lifecycle [email protected]~prestart: [email protected]
6 silly lifecycle [email protected]~prestart: no script for prestart, continuing
7 info lifecycle [email protected]~start: [email protected]
8 verbose lifecycle [email protected]~start: unsafe-perm in lifecycle true
9 verbose lifecycle [email protected]~start: PATH: /usr/share/npm/bin/node-gyp-bin:/opt/flood-pull/node_modules/.bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/snap/bin
10 verbose lifecycle [email protected]~start: CWD: /opt/flood-pull
11 silly lifecycle [email protected]~start: Args: [ '-c', 'node server/bin/start.js' ]
12 silly lifecycle [email protected]~start: Returned: code: 1  signal: null
13 info lifecycle [email protected]~start: Failed to exec start script
14 verbose stack Error: [email protected] start: `node server/bin/start.js`
14 verbose stack Exit status 1
14 verbose stack     at EventEmitter.<anonymous> (/usr/share/npm/lib/utils/lifecycle.js:232:16)
14 verbose stack     at emitTwo (events.js:87:13)
14 verbose stack     at EventEmitter.emit (events.js:172:7)
14 verbose stack     at ChildProcess.<anonymous> (/usr/share/npm/lib/utils/spawn.js:24:14)
14 verbose stack     at emitTwo (events.js:87:13)
14 verbose stack     at ChildProcess.emit (events.js:172:7)
14 verbose stack     at maybeClose (internal/child_process.js:821:16)
14 verbose stack     at Process.ChildProcess._handle.onexit (internal/child_process.js:211:5)
15 verbose pkgid [email protected]
16 verbose cwd /opt/flood-pull
17 error Linux 4.4.0-97-generic
18 error argv "/usr/bin/nodejs" "/usr/bin/npm" "start"
19 error node v4.2.6
20 error npm  v3.5.2
21 error code ELIFECYCLE
22 error [email protected] start: `node server/bin/start.js`
22 error Exit status 1
23 error Failed at the [email protected] start script 'node server/bin/start.js'.
23 error Make sure you have the latest version of node.js and npm installed.
23 error If you do, this is most likely a problem with the flood package,
23 error not with npm itself.
23 error Tell the author that this fails on your system:
23 error     node server/bin/start.js
23 error You can get information on how to open an issue for this project with:
23 error     npm bugs flood
23 error Or if that isn't available, you can get their info via:
23 error     npm owner ls flood
23 error There is likely additional logging output above.
24 verbose exit [ 1, true ]

Further tests I would suggest to do is see how many users this can hold at the same time, in the db, side by side, and with the insanely large amount of torrents this could mean. Imagine a scenario where a company like Feral would just start using this. Question is if that's something that this software should go in the direction of. Who knows, if the license is changed accordingly to make for-commerce use by paid-license only, and creating an admin panel for companies who would roll this software out to thousands of users, @jfurrow could get a nice little side-hustle :P But that's a whole 'nother issue.

After this is merged, I would like to see the issue of creating rtorrent instances from the server (maybe first offer a simple guide, help generating a .rtorrent.rc file, etc.) be explored a little further.

Really happy with this however, this software has some serious potential.

@zawapete
Copy link
Contributor Author

zawapete commented Dec 6, 2017

@jvacek , yes, I will improve UI experience in order to have proper configuration. anyway the configuration you have to setup doesn't differ from the one in config.js. I've no previous experience in react so if you or anyone else wants to address this in a PR on top of my fork is welcome.
As for the admin/acl for user, I would add in a different PR, since it's the already existing behavior that any logged user can add/delete any other user.

for Error: ENOENT: no such file or directory, rename './server/db/vhtSHwaE1Iad9siM/notifications.db~' -> './server/db/vhtSHwaE1Iad9siM/notifications.db': as far as I can see it's a bug in nedb library that results from a race condition when handling multiple "connection" to the same db. I still need to open an issue on they repository, you can do if you want. Since it's an issue in a dependency there's nothing I can do to address it here, unless we want to switch to another library/db, it's not even related to my PR (even if my code could be responsible for more chance to trigger the bug in nedb).

the second bug I never encountered, I did some research and it could be a problem with the node and npm versions you are using: according to package.json these are the requirements:

"node": ">=7.0.0",
"npm": "~5.3.0"

your debug log shows the following:

19 error node v4.2.6
20 error npm v3.5.2

Further tests I would suggest to do is see how many users this can hold at the same time, in the db, side by side, and with the insanely large amount of torrents this could mean

only the user db is shared, all the other dbs are isolated for the currently logged in users.
I'm currently using it with four users/rtorrent instances on socket, slowly replacing a rutorrent installation (that would be my ultimate goal, but the basic was to handle multiple rtorrent instances).
it would be totally cool if flood will replace rutorrent as most common choice for rtorrent web ui, and since they share the same gpl3 license there should be no problem on this side

rutorrent use json files as persistency layers, that's mostly like nedb, so unless nodejs has far worse performance than php I expect a similar outcome

Copy link

@jvacek jvacek left a comment

Choose a reason for hiding this comment

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

Currently works as intended, few UI improvements and input checking could be brushed up but good enough to roll out in my opinion.

@jvacek
Copy link

jvacek commented Dec 6, 2017

the second bug I never encountered, I did some research and it could be a problem with the node and > npm versions you are using: according to package.json these are the requirements:

"node": ">=7.0.0",
"npm": "~5.3.0"

your debug log shows the following:

19 error node v4.2.6
20 error npm v3.5.2

This must be an issue with my whole node version screwup, I'm running the entire thing as root, managing the node version using n, and that's about that. I'll need to do some serious maintenance on this soon. Otherwise I have not found any other bugs.

@zawapete
Copy link
Contributor Author

zawapete commented Dec 6, 2017

if the PR get accepted, before merging I will add an automatic migration for existing installation to the new db/config structure

@jvacek jvacek mentioned this pull request Dec 6, 2017
@jfurrow
Copy link
Member

jfurrow commented Jan 3, 2018

Thanks for the PR @zawapete!

I still have the same concerns I expressed in Slack with regard to the service instances.

In this PR, we're creating new instances of the services on-the-fly in a number of places. In master, we're creating a single instance of each service immediately when the server starts.

With Flood's current architecture, we'll need to do the same thing — every user will need their own isolated instances of each service, and those instances need to be created as soon as the server begins running. Whenever a service's method is called in the application, the callee will need to retrieve the service instance for the user that initiated the request.

To manage these instances, I think it makes sense to create a module that instantiates and stores the services for each user when the server starts, and exposes some getter methods to retrieve the services instances. Something simple like this would be ideal:

const torrentServices = new Map();
const notificationServices = new Map();
// etc

users.forEach(userId => {
  torrentServices.set(userId, new TorrentService());
  notificationServices.set(userId, new NotificationService());
  // etc
});

module.exports = {
  getTorrentService: userId => torrentServices.get(userId),
  getNotificationService: userId => notificationServices.get(userId)
  // etc
};

After thinking through these things some more, I'm wondering if it would be better to create an instance of each service per rTorrent instance, rather than per user. So if two users share the same rTorrent instance, they'll both access the same service instances. What do you think? (I think I'm okay with deferring that work to a separate PR, because it probably requires differentiating between user-related services and client-related services.)

@zawapete
Copy link
Contributor Author

zawapete commented Jan 3, 2018

@jfurrow I tried something like you suggested in a commit I deleted: having the instance instantiated at request level in a middleware. it ended up with some issues with duplicated notifications and I removed it
I will try your solution, but I wouldn't go for instatiating every service for every user at startup, since you would have instances for not logged users that you don't actually need. also you can register an user after the startup and you would miss the services' instances, so that some sort of initialization on demand would be still required
I'm not exactly sure how to achieve it in node.js but the best way to go would be to have only one instance for every service for every (and only) logged users that will be purged when the user logout (or after some inactivities, like for the activity stream). I will try to come out with a commit in the weekend

@bananabomb59
Copy link

bananabomb59 commented Jan 21, 2018

Hello everyone,

First of all, thank you @zawapete for this multi-users feature that I was needing to setup a private-shared seedbox platform.

I just wanted to know if there was an update on the db issues that makes flood crash ? After a download is finished, the notification icon goes crazy (displays 50+ times the same information) then the server crashes :

GET /api/notifications?limit=10&start=0 200 10.978 ms - -
/srv/seedbox/flood/node_modules/nedb/lib/datastore.js:77
    if (err) { throw err; }
               ^


Error: ENOENT: no such file or directory, rename './server/db/2Phd3rhT33FVyEXK/notifications.db~' -> './server/db/2Phd3rhT33FVyEXK/notifications.db'
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! [email protected] start: `node server/bin/start.js`
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the [email protected] start script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.

npm ERR! A complete log of this run can be found in:
npm ERR!     /root/.npm/_logs/2018-01-21T15_03_57_677Z-debug.log
$ sudo less /root/.npm/_logs/2018-01-21T15_03_57_677Z-debug.log
0 info it worked if it ends with ok
1 verbose cli [ '/usr/bin/node', '/usr/bin/npm', 'start' ]
2 info using [email protected]
3 info using [email protected]
4 verbose run-script [ 'prestart', 'start', 'poststart' ]
5 info lifecycle [email protected]~prestart: [email protected]
6 info lifecycle [email protected]~start: [email protected]
7 verbose lifecycle [email protected]~start: unsafe-perm in lifecycle true
8 verbose lifecycle [email protected]~start: PATH: /usr/lib/node_modules/npm/node_modules/npm-lifecycle/node-gyp-bin:/srv/seedbox/flood/node_modules/.bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
9 verbose lifecycle [email protected]~start: CWD: /srv/seedbox/flood
10 silly lifecycle [email protected]~start: Args: [ '-c', 'node server/bin/start.js' ]
11 silly lifecycle [email protected]~start: Returned: code: 1  signal: null
12 info lifecycle [email protected]~start: Failed to exec start script
13 verbose stack Error: [email protected] start: `node server/bin/start.js`
13 verbose stack Exit status 1
13 verbose stack  at EventEmitter.<anonymous> (/usr/lib/node_modules/npm/node_modules/npm-lifecycle/index.js:285:16)
13 verbose stack  at emitTwo (events.js:126:13)
13 verbose stack  at EventEmitter.emit (events.js:214:7)
13 verbose stack  at ChildProcess.<anonymous> (/usr/lib/node_modules/npm/node_modules/npm-lifecycle/lib/spawn.js:55:14)
13 verbose stack  at emitTwo (events.js:126:13)
13 verbose stack  at ChildProcess.emit (events.js:214:7)
13 verbose stack  at maybeClose (internal/child_process.js:925:16)
13 verbose stack  at Process.ChildProcess._handle.onexit (internal/child_process.js:209:5)
14 verbose pkgid [email protected]
15 verbose cwd /srv/seedbox/flood
16 verbose Linux 4.9.0-5-amd64
17 verbose argv "/usr/bin/node" "/usr/bin/npm" "start"
18 verbose node v8.9.4
19 verbose npm  v5.6.0
20 error code ELIFECYCLE
21 error errno 1
22 error [email protected] start: `node server/bin/start.js`
22 error Exit status 1
23 error Failed at the [email protected] start script.
23 error This is probably not a problem with npm. There is likely additional logging output above.
24 verbose exit [ 1, true ]

Did a quick digging, turns out the notifications db is continuously updated with the same information (well, if I understand the error log correctly, "written over" would be more accurate than "updated") :

...
{"ts":1516549315051,"data":{"name":"dragora-2.2-plus.iso"},"id":"notification.torrent.finished","read":false,"_id":"fc0odbs3gOdiyUlx"}
{"ts":1516549465369,"data":{"name":"dragora-2.2-plus.iso"},"id":"notification.torrent.finished","read":false,"_id":"fz3GdJO74eJYzV85"}
{"ts":1516549405244,"data":{"name":"dragora-2.2-plus.iso"},"id":"notification.torrent.finished","read":false,"_id":"g5q7J3ET816nfPAJ"}
{"ts":1516549286997,"data":{"name":"dragora-2.2-plus.iso"},"id":"notification.torrent.finished","read":false,"_id":"gWDqCjPsnNFnp0Oa"}
{"ts":1516549473384,"data":{"name":"dragora-2.2-plus.iso"},"id":"notification.torrent.finished","read":false,"_id":"gWzVM6LLRkAbfRVl"}
{"ts":1516549311043,"data":{"name":"dragora-2.2-plus.iso"},"id":"notification.torrent.finished","read":false,"_id":"gZ6VQMHB8oBEitHD"}
{"ts":1516549313047,"data":{"name":"dragora-2.2-plus.iso"},"id":"notification.torrent.finished","read":false,"_id":"gdQG1ktMDY32yxRS"}
{"ts":1516549533515,"data":{"name":"dragora-2.2-plus.iso"},"id":"notification.torrent.finished","read":false,"_id":"gko1gxQPKCuqn6Lz"}
{"ts":1516549461362,"data":{"name":"dragora-2.2-plus.iso"},"id":"notification.torrent.finished","read":false,"_id":"hGv5Pmk7ukEIHvUx"}
{"ts":1516549531511,"data":{"name":"dragora-2.2-plus.iso"},"id":"notification.torrent.finished","read":false,"_id":"hsnTx5cteWGJYc2P"}
{"ts":1516549433301,"data":{"name":"dragora-2.2-plus.iso"},"id":"notification.torrent.finished","read":false,"_id":"ip9KeBq5hZo4hVTe"}
...

So far, for a download that ended a few minutes ago I have more than 280 entries likes this, and still growing. At some point 2 write operations will concur (if I display the notification list in the GUI most probably ?) and the server will crash.

I'm not good enough a developer to go deeper in the analysis, but there's definitely something that needs fixing here.

Let me know though if I can be of any help

Thank you

@zawapete
Copy link
Contributor Author

@bananabomb59, thank you for giving my branch a try.
for the db exception: it is a problem in nedb, you can find the PR to add a locking mechanism here: louischatriot/nedb#535 the project seems to be stale anyway

as for the multiple notification, that could be a bug in my branch, even if I wasn't able to reproduce. can you tell me the commit you're testing with?

@bananabomb59
Copy link

1f5fda3 apparently (this is my first use of git, I've stopped developing a while ago ^^)

I'll update to the latest commit to see if I still have the issue.

@bananabomb59
Copy link

OK updated to latest commit, I don't seem to have the multiple notifications issue. The notification behavior is still a bit erratic (sometimes the notification is triggered when the download is complete, sometimes it's not), but it's far less problematic.

What's more problematic though is that twice now since I've started testing this commit, the rtorrent instance associated to one of my users has crashed. It seems to have happened when deleting a torrent and its data in the GUI, but it's not happening every time I do that. I'll give it some more tries later today, to see if I can identify a pattern to reproduce the issue.

@zawapete
Copy link
Contributor Author

zawapete commented Jan 21, 2018

sometimes the notification is triggered when the download is complete, sometimes it's not

I encountered this problem as well: in order to trigger the notification the original code check the previous download percentage of the torrent and the current one: if the previous is < 100 and the current == 100 then it triggers the notifications (see https://github.com/jfurrow/flood/blob/master/server/services/torrentService.js#L315-L316). it seems that sometimes the interval the torrent data are queried on doesn't meet this condition

@bananabomb59
Copy link

bananabomb59 commented Jan 21, 2018

Yes I figured it'd be something like this. Not a biggie then.

About my other issue with rtorrent crashing twice earlier, I've set rtorrent in extra-verbose mode and restarded it, but by the inevitable Murphy's law it hasn't crashed again in the numerous tests of downloads and deletions I've made for the last hour. I don't believe in coincidence so I'm still expecting the anomaly to happen again, but can't say for sure when and how. I'll let you know when it does.

if (!notificationServicesInterval.get(userId)) {
notificationServicesInterval.set(userId,
setInterval(() => notificationServices.delete(userId), servicesPurgeInterval)
);
Copy link
Member

Choose a reason for hiding this comment

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

What's the reason for purging this every 10 minutes?

@jfurrow
Copy link
Member

jfurrow commented Jan 28, 2018

@zawapete Can you explain more about the database issue? If I understand it correctly, you're loading multiple instances of the same database — presumably once per user. Is that correct? If so, it would be better if Flood loaded a single instance for the single database, right?

Overall this is working pretty well for me, so far. I'd like to hear more about the database issue first and see if we can find a good solution, but I'm inclined to accept this PR into a feature branch. I'd like to work a bit more on this experience before merging into master — specifically improving the rtorrent connection error handling.

@jfurrow
Copy link
Member

jfurrow commented Jan 28, 2018

Some bugs I've noticed which should be fixed before merging into the feature branch (I may find more later, just FYI):

  • The notifications bug mentioned above
  • When I tested this with two active users, the data displayed in the transfer rate history graph was delayed by a few minutes. On the x-axis of the graph, the right-most point should be data from just a few seconds ago, but data was from over a minute ago. There's probably a bug in the history service.

User A:
screen shot 2018-01-28 at 3 36 35 pm

User B:
screen shot 2018-01-28 at 3 36 27 pm

@jfurrow jfurrow changed the base branch from master to feature/multi-user January 28, 2018 23:49
@zawapete
Copy link
Contributor Author

zawapete commented Feb 2, 2018

@jfurrow

Can you explain more about the database issue?

I was loading concurrently the same database, and nedb has an issue with it (there's a PR to introduce a locking mechanism but the project seems to be stale). basically when you load a nedb database the library creates a file with name.db~ as a backup and then it deletes it. if you load the database two times at almost the same time when the second load is processed and tries to delete the backup file this was already deleted by the first load, resulting in an exception.
note that this was true until the last commit, since now we have only one shared instance of every services (and so db load)

What's the reason for purging this every 10 minutes?

we don't want to have services instances in memory when the user is not logged in: we can purge on logout but that's not reliable, since the user could just close the browser without logging out. I put a in place this purging time every 10 minutes to improve the memory footprint basically. in case the user is still using flood after that times (or he comes back), the services are instantiated seamless again

I would check in the mentioned bugs. also before merging I would like to add an isAdmin flag to the first registered user that would come in handy if we will ever limit user creation access in the future. doing it so would solve the problem when it will present while trying to add it later would require some kind of troublesome migration, what do you think?

@jfurrow
Copy link
Member

jfurrow commented Mar 5, 2018

@zawapete This seems to be working really well! Thanks so much for your contributions and patience.

I think an isAdmin flag makes sense, so feel free to add it if you want. I'd like to get this merged into the feature branch and then I'll start polishing the UI for it (just a few minor things).

I don't really like the 10 minute purging, but let's go with it for now and see how it works.

@zawapete
Copy link
Contributor Author

zawapete commented Mar 5, 2018

@jfurrow isAdmin flag added. I removed the 10 mins purging for torrentservice otherwise we'd lose notification, but all the other services doesn't need to stay in memory (and I'd prefer a cached and resumable instance for the torrent one, but there's too much work for it at the moment)

the PR is finished on my side. last thing missing is a migration to new db structure for existing installations: I don't know if we want to add it (maybe as a separate npm target?)

@jfurrow
Copy link
Member

jfurrow commented Mar 14, 2018

@zawapete Awesome, I'll merge this into the feature branch and start testing it locally. Thanks for all your work!

@jfurrow jfurrow merged commit b76434d into Flood-UI:feature/multi-user Mar 14, 2018
@jfurrow jfurrow mentioned this pull request Mar 14, 2018
15 tasks
jfurrow pushed a commit that referenced this pull request May 21, 2018
* Handling multiple rtorrent instances

* performance issue addressing

* fix wrong conflict resolution

* performances

* purge services instance every 10 mins

* last fixes

* avoid duplicated reducers
jfurrow pushed a commit that referenced this pull request May 21, 2018
* Handling multiple rtorrent instances

* performance issue addressing

* fix wrong conflict resolution

* performances

* purge services instance every 10 mins

* last fixes

* avoid duplicated reducers
jfurrow pushed a commit that referenced this pull request Aug 18, 2018
* Handling multiple rtorrent instances

* performance issue addressing

* fix wrong conflict resolution

* performances

* purge services instance every 10 mins

* last fixes

* avoid duplicated reducers
jfurrow added a commit that referenced this pull request Sep 2, 2018
* Multi rtorrent instances support (#549)

* Handling multiple rtorrent instances

* performance issue addressing

* fix wrong conflict resolution

* performances

* purge services instance every 10 mins

* last fixes

* avoid duplicated reducers

* Adjusts UI of rtorrent connection form fields (#639)

* Multi rtorrent instance cleanup (#676)

* Cleans up multi-user logic.

* Rename clientRequestService to clientGatewayService

* [multi-user] Adds prompt to fix rtorrent connection failure (#681)

* Adds ability to update user

* Add connection test endpoints and client actions

* Listen to client connectivity change events

* Separates scgiUtil from clientRequestManager

* Adds BaseService

* Services extend BaseService

* Listen for connetion change events in client

* Reorganizes app structure

* Adds prompt to correct per-user client interruption

* Fixes linting errors

* Removes debugging stuff

* Fixes Size rendering

* Fixes moveTorrents

* Adds migration step for legacy database entries (#686)

* Use FormattedMessage

* Updates documentation

* Fixes migration script for new installs

* Updates dependencies

* Moves string to i18n

* Updates deps
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants