neumino / thinky

JavaScript ORM for RethinkDB
http://justonepixel.com/thinky/
Other
1.12k stars 128 forks source link

Safe mode #473

Open dtoubelis opened 8 years ago

dtoubelis commented 8 years ago

I have an application that I'm deploying into production environment that consists of 8 application server nodes accessing rethinkdb consisting of 4 replicas. The problem I'm facing is that if some tables/indices need to be created in the database multiple instances do it in parallel colliding with each other and corrupting the database (creating duplicate tables with identical names on different partitions). Right now I run database reconditioning code before deploying a new version of the app but this is not full proof. What I wonder if it is possible to prevent thinky from creating any data structures by passing a configuration option?

This is quite common feature with other ORM/ODM and I was pretty certain that thinky should be able to do it as well but I'm not finding anything in the documentation.

neumino commented 8 years ago

Sorry for the late answer.

The expectation is to make schema backward compatible. The steps then are:

  1. Deploy a dummy script loading thinky and all your new schema/indexes
  2. When that's done, deploy your server using these new schema.
dtoubelis commented 8 years ago

@neumino , Thank you for the answer. What I was asking for is a safety switch - that under no circumstances changes are made to the database schema if it is on. I think that would be invaluable for production deployments.

neumino commented 8 years ago

There's no schema at the database level, so you

neumino commented 8 years ago

There's no schema at the database level, so you can't strongly enforce a schema.

dtoubelis commented 8 years ago

By schema I actually meant tables and indices, sorry about the confusion. We solved concurrency problem so far but it is not foolproof. Somebody may inadvertently make changes to deployment scripts and this may cause database corruption. So what I was thinking is to deploy all application servers with the safety switch on that under no circumstances they can create, modify or delete tables or indices and only have this switch off for a management instance. What do you think?

neumino commented 8 years ago

Sorry for the late answer, I wanted to finish updating rethinkdbdash and thinky for RethinkDB 2.3. The good news is that RethinkDB 2.3 is out and it added support for users permission. So if you use by default a user with only read and write access, it won't be able to create indexes/reshard your table etc.

Let me know if that answer your question.

dtoubelis commented 8 years ago

I'm talking about slightly different use case here. The safe parameter would only disable creation of tables/indices but would not affect read/write permissions. This feature exists in hibernate, waterline, mongoose and I'm pretty sure in sequelize as well. It is not feature of the database but of the ORM/ODM framework. It would be nice to see something similar in thinky.

neumino commented 8 years ago

Is init: false what you are looking for?

dtoubelis commented 8 years ago

I could not find it in the documentation but I can see it in the source and yes, this would solve my problem. It is relatively easy to do in our code because all our models are declared in a single file, but it may be challenging if there is one file per model. Generally, I was thinking more along these lines:

var thinky = require("thinky")({
  safe: true
});

with safe: true being default. So, if you consider it for future that would be awesome. And thanks for the great job you've done already :-)

neumino commented 8 years ago

Oh I see, I thought I added init on the top level config, but looking at the code, it's clearly not there.

Reopening with the scope of making the init options work on the top level config

var thinky = require('thinky')({
  init: false
})

I'm not a big fan of naming the option safe though because it doesn't technically prevent someone from writing something like this

var r = thinky.r;
r.tableCreate('bar').run()
dtoubelis commented 8 years ago

I think it doesn't really matter if it is init: false or safe: true as long as this option is available. I personally like init better as well but for some reasons safe is the one used by other frameworks. Thanks for reopening this :-)