I’m considering using Elixir to build a real time app, and I’m just wondering what happens when someone changes the database directly. Is there any way that the Elixir servers can be notified of the change and update accordingly?
What do you mean by “someone changes the database directly”?
Do you mean:
- someone adds/removes/updates records in the database
- someone amends the database schema
- someone drops/recreates the database on database server (?)
- someone upgrades database
Yes. Someone adds/edits/deletes a record from the database
I assume you have Elixir/Phoenix app in mind.
Nothing special happens. In fact, edits made by one request handler within Phoenix app have exactly the same effect as edits done by someone using psql or pgadmin directly.
On next page refresh the new data will be displayed in both cases.
Architecturally speaking, these days “that” is considered a bad idea. In service design this is part of service autonomy - i.e. an application should have full control over it’s own data (with no one else messing about in it) and data owned by other applications needs to be obtained via their service API.
Strong cohesion and loose coupling—with database integration, we lose both things. Database integration makes it easy for services to share data, but does nothing about sharing behavior. Our internal representation is exposed over the wire to our consumers, and it can be very difficult to avoid making breaking changes, which inevitably leads to a fear of any change at all. Avoid at (nearly) all costs.
Now we aren’t talking about services as such - but some of the wisdom is more broadly applicable. Basically by using the database as an integration point you are allowing more than one application to become tightly coupled with the database schema - this also increases the pressure to push more and more business logic into the database via triggers and stored procedures. Ultimately sharing a database is an easy solution that is often synonymous to embarking on the road to an unholy, complected mess.
If more than one application has to have access to the data then it may be time to wrap the persistent storage in a service - which in Elixir could just be another OTP application.
It could have nothing to do with running multiple apps against same DB, one might be looking for a more reactive pattern to propagate changes.
I’m not sure I follow - the database’s responsibility is to store data on behalf of the application that owns it - it is the responsibility of the application (or service) that owns the data to ensure that other interested parties are notified of relevant changes (provided that is even necessary).
- The data being changed is of interest at this point in time to at least one party - otherwise it wouldn’t be changing.
- The data should only be changed through the application that owns it, as it is also enforces all the domain rules.
- If other parties are also currently interested in the change of that data then they should be subscribed to events of the domain that the data belongs to.
- Once the application successfully stores the change in the database it has the responsibility to trigger any relevant domain events (the details of which could be delegated to some intermediary).
The database is an important part of any application/service - trouble starts once it starts becoming the application.
Is this with Meteor.js in mind?
Yes it is. How things worked with meteor, any source I changed would
automatically show up on the client and every meteor instance connected to
the db was aware of the changes.
I am not arguing for or against doing this I am pointing out there are use cases that are not related to multiple apps sharing the same DB.
Why are your trying to build an application in the “Meteor way” - without Meteor? What are you hoping to gain over just staying with Meteor? Just curious.
I have a Meteor application. One essential part of it I’m considering moving over to Phoenix due to its highly scalable real-time nature.
I’m not trying to do things any way. I’m still very much a beginner and am trying to work out the best way to do things, and what is the correct way to think of things if or when I move to Elixir.
Check the Boltun library
One could build Meteor-like functionality on top of Elixir/Phoenix/Ecto/Postgres. But this is not how it works by default.
I also suspect that cloning Meteor’s approach in Elixir wouldn’t exactly play to Elixir’s strengths. Now I know nothing of Meteor but is seems that the “reactive” aspect of its
LiveResultsSet (LRS) isn’t supported directly by MongoDB but via Meteor either doing a “poll-and-diff” or by observing MongoDB’s oplog.
Both sql-notify and boltun are solutions that are specific to PostgreSQL - so they won’t work for other databases (for example Ecto 2.0 currently also supports MySQL and others may be added in the future).
From a design perspective it makes more sense that the chain of events that leads to the DB update should also emit a notification that informs the rest of the world of the update - rather than trying to detect it at the database level.
Which often translates to “more effort to initially implement” - especially as you have to make some decisions upfront that Meteor has already made for you - for better or worse.
It strikes me that Meteor seems to make a lot of trade-offs and concessions upfront so that fledgling ventures can get off the ground fairly quickly while having some leeway to adapt as they discover what their business needs actually are. The Meteor approach may have enough “headroom” for growth for a lot of use cases - it may take some time before “Meteor doesn’t scale well” - and in many cases it may never get to that point.
An Elixir/Phoenix solution could require additional work upfront as some of the “bits” that Meteor supplies simply aren’t there - but that only matters if those “bits” are actually necessary to solve the problem at hand. Erlang/OTP/Elixir is all about messages/notifications. So one could initially start with some simplistic way of handling messages/notifications, refactoring later when it becomes more apparent where the potential bottlenecks are as one isn’t locked into “one way” of doing things (e.g. by detecting changes on the database level - though Meteor also has the Distributed Data Protocol (DDP)).