CytubeBot fails to create a working database
When CytubeBot creates it's database, it does it in such a way that it'll crash when it tries to supply values to the users table. I have fixed this on my own machine by manually dropping the users table and creating a new one with this command: CREATE TABLE users(uname TEXT, blacklisted TEXT, block TEXT, rank INTEGER, primary key(uname));
I believe the bug exists in line 22 of lib/database.js, which reads:
this.db.run("CREATE TABLE IF NOT EXISTS users(uname TEXT, blacklisted TEXT, block TEXT, primary key(uname))")
but should read:
this.db.run("CREATE TABLE IF NOT EXISTS users(uname TEXT, blacklisted TEXT, block TEXT, rank INTEGER, primary key(uname))")
Adding "rank INTEGER," which seems to have been left out.
Rank should be added when it updates the tables though. https://github.com/nuclearace/CytubeBot/blob/master/lib/database.js#L40
For me, it crashed before it got to that point.
http://pastebin.com/QkWEVWy9
The database initialization code is fragile and has race conditions. What probably happened is the disk was slow and the network was fast so the bot joined the room and got the list of users before running ALTER TABLE users ADD rank INTEGER.
-
serialize()does not lock the database. Other threads can still put new commands onto the queue. Your use ofupdate.run(callback)gives another thread ample opportunity to run a command (inserting users, in this case) before theALTER TABLEcommand is put onto the queue. Even without the callback other threads could still interleave commands with the initialization code. - The version number is incremented before issuing the
ALTER TABLEcommand. If theALTER TABLEcommand fails it will never be reattempted because the version is already '1'. These should be done together in a transaction so that if one fails both are rolled back and reattempted when the bot restarts. -
parallelize()is never called unless it's the first time the bot is run. On all subsequent runs the database will remain in serial mode. I'd image the database is one of your bottlenecks, especially with no indices.
The trick for #1 is to lock the database during initialization but not require threads to acquire locks after that point or you'll remove any parallelism.