Meteor.userId lost on server changes dev reload - meteor

I'm building a somewhat big application. When changing code the server restart and force refresh on the client.
The client keep his session data, but I seem to lose the Meteor.Collection previously sync data, forcing my user to re-sync everything.
I use 0.5.7(did not see anything in 0.5.8 about that)
Is that the expected behavior or I'm I missing something?
This can be tested by adding something like that at your client start (Assuming Components is your Meteor.Collection)
console.log("Length: ", Components.find().fetch().length);

No, you're not missing anything. The collection data should be re-synced on code pushes. However, if your collection data takes more than a second or two to load in, you should look into trying to send less data to the client by creating finer-grained subscriptions that only send data the client needs at the moment.

Related

Database rollback on API response failure

A customer of ours is very persistent that they expect this "from any API" (meaning they don't want to pay for the changes). I seem to have trouble finding clear information on this though.
Say we have an API that creates an appointment for a calendar. Server-side everything was successful, data is committed to the database. API tries to send the HTTP 201 (Created) response, but something goes wrong there. Client ignores the response, or connection dropped, ...
They want our API to undo the database changes in that particular situation.
The question is not how to do this, but rather if this is something most APIs do? Is this standard behavior? Or something similar like refusing duplicate create requests?
The difficult part of course is to actually know if an API has failed to send the response, and as far as I am concerned with respect to the crux of the question, it is not a usual behavior implemented. If the user willingly inputs the data, you can go ahead and store it. If the response doesn't return properly due to timeouts (you are not responsible for user "ignoring" the response), then the client side code can refresh on failure and load fresh data. And the user can delete inputted data themselves(given you provide an endpoint for that)
Depending on the database, it is possible to make all database changes of an API reversible. For example, with SQL, you use [SQL transactions][1] using commit, rollback and savepoints. There is most likely a similar mechanism available for noSQL.

How to make Meteor changes instant?

Meteor is supposed to pre-load a small part of Mongo client-side so that it can simulate changes to the DB. Thus making any changes to the page happen instantly while the real DB update happens in the background.
However, on my site I'm seeing a 1-2 second delay on simple actions that make changes to the DB, such as deleting a post.
Is there some extra coding that needs to be done to ensure the client-side simulation works?
As Michel Floyd Pointed out, if your meteor method is defined as server only code, there is no way to simulate the method call on the client.
Try moving Meteor method declarations into shared code, and see if that changes latency time.
also, without seeing some code and project structure the problem could be else where...
If you are using server-side method only, make sure your Mongodb has oplog tailing enabled, so that the change is picked up immediately and sent to the client. If you are using like a hosted db, like the free mlab, it's possible you have no oplog, the meteor falls back to querying the db periodically to check for changes.
But in any case, if the method is server side only, you will always have delays. Like mentioned in this thread, move the method definition outside the server folder (like /lib) só that the method becomes available on th client.

Would real world Meteor application use server side Methods almost exclusively?

I'm learning Meteor and fundamentally enjoy how fast I can build data driven applications however as I went through the Creating Posts chapter in the Discover Meteor book I learned about using server side Methods. Specifically the primary reason (and there are a number of very valid reasons to use these) was because of the timestamp. You wouldn't want to rely on the client date/time, you'd want to use the server date/time.
Makes sense except that in almost every application I've ever built we store date/time of row create/update in a column. Effectively every single create or update to the database records date/time which in Meteor now looks like I would need to use server side Methods to ensure data integrity.
If I'm understanding correctly that pretty much eliminates the ease of use and real-time nature of a client side Collection because I'll need to use Methods for almost every single update and create to our databases.
Just wanted to check and see how everyone else is doing this in the real world. Are you just querying a server side Method that just returns the date/time and then using client side Collection or something else?
Thanks!
The short answer to this question is that yes, every operation that affects the server's database will go through a server-side method. The only difference is whether you are defining this method explicitly or not.
When you are just getting started with Meteor, you will probably do insert/update/remove operations directly on client collections using validators, which check for whether the operation is allowed. This usage is actually calling predefined methods on both the server and client: (for a collection named foo the you have /foo/insert, for example) which simply checks the specified validators before doing the operation. As you become more familiar with Meteor you will probably override these default methods, for reasons you described (among others.)
When using your own methods, you will typically want to define a method both on the server and the client, just as the default collection functions do for you. This is because of Meteor's latency compensation, which allows most client operations to be reflected immediately in the browser without any noticeable lag, as long as they are permitted. Meteor does this by first simulating the effect of a method call in the client, updating the client's cached data temporarily, then sending the actual method call to the server. If the server's method causes a different set of changes than the client's simulation, the client's cache will be updated to reflect this when the server method returns. This also means that if the client's method would have done the same as the server, we've basically allowed for an instant operation from the perspective of the client.
By defining your own methods on the server and client, you can extend this to fill your own needs. For example, if you want to insert timestamps on updates, have the client insert whatever timestamp in the simulation method. The server will insert an authoritative timestamp, which will replace the client's timestamp when the method returns. From the client's perspective, the insert operation will be instant, except for an update to the timestamp if the client's time happens to be way off. (By the way, you may want to check out my timesync package for displaying relative server time accurately on the client.)
A final note: it's good to understand what scope you are doing collection operations in, as this was one of the this that originally confused me about Meteor. For example, if you have a collection instance in the client Foo, Foo.insert() in normal client code will call the default pair of client/server methods. However, Foo.insert() in a client method will run only in a simulation and will never call server code - so you will need to define the same method on the server and make sure you do Foo.insert() there as well, for the method to work properly.
A good rule of thumb for moving forward is to replace groups of validated collection operations with your own methods that do the same operations, and then adding specific extra features on the server and client respectively.
In short— yes!
Publications exist to send out a 'live', and dynamic, subset of the database to the client, sending DDP added messages for existing records, followed by a ready, and then added, changed, and deleted messages to keep the client's cache consistent.
Methods exist to- directly, or indirectly— cause Mongo Updates, and like it was mentioned by Andrew, they are always in use.
But truly, because of Meteor's publication architecture, any edits to collections that are currently being published to at least one client, will be published via DDP - regardless of the source of the change to Mongo - even an outside process.

SignalR - storing client information

I've started experimenting with SignalR. I've been trying to come up with a flexible way of storing information about each connected client. For example, storing the name in a chat app rather than passing it with each message.
At the moment, I have a static dictionary which matches the connectionId to an object which contains these properties. I add to this dictionary on connection, and remove on disconnection.
The issue I'm having is that I don't seem to get all disconnect events. If I close a tab in Chrome, the disconnect seems to go through. However, if I rapidly reload a tab, the disconnect doesn't seem to occur (at least not 'cleanly'). For example, if I reload the same tab over and over, it'll tell me my dictionary has multiple items when it should - in theory still be one.
Is there a standard way of storing this kind of per-connection information? Otherwise, what might be causing the issue I'm having?
You are actually handling connection id data correctly. Ensure that you are only instantiating your user data in OnConnected and uninstantiating it in OnDisconnected.
When spamming refresh on your page there are situations which result in the OnDisconnected event not being triggered immediately. However you should not worry about this because SignalR will actually time-out the connection and trigger the OnDisconnected event after a designated timeout (DisconnectTimeout).
If you do come across scenarios where there is not a 1-to-1 correlation for OnConnected and OnDisconnected events (after a significant amount of time) make sure to file a bug at https://github.com/SignalR/SignalR/issues.
Lastly if you're looking at doing some advanced chat mechanics and looking for some inspiration check out JabbR, it's open source!
https://github.com/davidfowl/JabbR
Hope this helps!

intercept data changes and alter/validate from a server

I'm working on a solution to intercept changes to the data from our node.js server and validate/alter them before they are stored/synced to other clients.
Any strategies or suggestions on how to solve this with the current code base?
Currently, it seems like the only option is to rewrite it post-sync operation. That would mean each client would probably receive the sync (including the server), then the server would rewrite the data and trigger a second sync.
To help understand the context of the question, here's what seems like an ideal strategy for my needs:
server gets a special token/key not available to clients (when security comes about)
server registers a dependency injection like firebase.child('widgets').beforeSync(myCallback)
client syncs data
server callback is notified
server modifies or validates the data
if valid, it returns it to firebase for sync ops
if invalid, aborts the sync with an error which is returned to the client
Thanks for sharing your ideas!
We've considered this type of approach. You can actually simulate this sort of behavior by structuring your data so that there is an "unvalidated" tree and a "validated" tree.
The "unvalidated" tree would be writeable by the client and the server would monitor it for changes. When a change occurs it would validate the data, and if it passes it would copy it into the "validated" tree which is only writeable by the server. You could pass errors back to the client through Firebase data as well when the validation fails.
This behavior could be packaged into a library that provides the behavior you describe. We may add this as core functionality as well, but we're still researching a variety of options.

Resources