Can Meteor call a method on the server twice if the client gets disconnected? - meteor

In LivedataConnection, line 357, there's a comment that says:
// Sends the method message to the server. May be called additional times if
// we lose the connection and reconnect before receiving a result.
Does this mean that if a client calls a method and gets disconnected before the method returns, it will re-call that message when it reconnects? What if that method isn't idempotent?

Basically, yes, as of version 1.0. Meteor methods are not idempotent. I've reported this issue, as have others, and it's basically confirmed by a core developer:
https://github.com/meteor/meteor/issues/2407#issuecomment-52375372
The best way to fix this in most cases is to try and write a unique key to the database, associating with a method request, or to make use of some other clever conditional database updates. There are some discussions about how to do that in these threads:
https://groups.google.com/d/msg/meteor-talk/j1YF7JO5Rdo/cYHR5kbhC8UJ
https://stackoverflow.com/a/26430334/586086

Related

Grpc C++: How to wait until a unary request has been sent?

I'm writing a wrapper around gRPC unary calls, but I'm having an issue: let's say I have a ClientAsyncResponseReader object which is created and starts a request like so
response_reader_ = std::unique_ptr<grpc::ClientAsyncResponseReader<ResponseType>>(
grpc::internal::ClientAsyncResponseReaderFactory<ResponseType>::Create(
channel.get(), completion_queue, rpc_method, &client_context_, request, true
)
);
response_reader_->Finish(
response_sharedptr_.get(), status_sharedptr_.get(), static_cast<void*>(some_tag)
);
// Set a breakpoint here
where all of the arguments are valid.
I was under the impression that when the Finish call returned, the request object was guaranteed to have been sent out over the wire. However by setting a breakpoint after that Finish() call (in the client program, to be clear) and inspecting my server's logs, I've discovered that the server does not log the request until after I resume from the breakpoint.
This would seem to indicate that there's something else I need to wait on in order to ensure that the request is really sent out: and moreover, that the thread executing the code above still has some sort of role in sending out the request which appears post-breakpoint.
Of course, perhaps my assumptions are wrong and the server isn't logging the request as soon as it comes in. If not though, then clearly I don't understand gRPC's semantics as well as I should, so I was hoping for some more experienced insight.
You can see the code for my unary call abstraction here. It should be sufficient, but if anything else is required I'm happy to provide it.
EDIT: The plot thickens. After setting a breakpoint on the server's handler for the incoming requests, it looks like the call to Finish generally does "ensure" that the request has been sent out: except for the first request sent by the process. I guess that there is some state maintained either in grpc::channel or maybe even in grpc::completion_queue which is delaying the initial request
From the documentation
response_reader_ = std::unique_ptr<grpc::ClientAsyncResponseReader<ResponseType>>(
grpc::internal::ClientAsyncResponseReaderFactory<ResponseType>::Create(
channel.get(), completion_queue, rpc_method, &client_context_, request, true
)
);
This will start a call and write the request out (start=true). This function does not have a tag parameter. So there is no way the completion queue can notify when the call start is finished. Calling an RPC method is a bit complicated, it basically involves creating the network packet and putting it in the wire. It can fail if there is a transient failure of the transport or the channel completely gone or the user did something stupid. Another thing, why we need the tag notification is that the completion queue is really a contention point. All RPC objects talk to this, it can happen completion queue is not free and the request is still pending.
response_reader_->Finish(
response_sharedptr_.get(), status_sharedptr_.get(), static_cast<void*>(some_tag)
This one will request the RPC runtime to receive the server's response. The output is when the server response arrives, then the completion queue will notify the client. At this point. we assume that there is no error on the client side, everything okay and the request is already in flight. So the status of Finish call will never be false for unary rpc.
This would seem to indicate that there's something else I need to wait on in order to ensure that the request is really sent out: and moreover, that the thread executing the code above still has some sort of role in sending out the request which appears post-breakpoint.
Perhaps, you want to reuse the request object(I did some experiments on that). For me, I keep the request object in memory till the response arrives. There is no way to guarantee that the request object won't be required after the create call.

Meteor CPU load: Method call vs Subscription

What is the CPU costless between sending data to a client via publish/subscription and via Method calls?
My answer is going to assume that you simply want to send data to the client:
It depends on what you want to do. If you want realtime updates the subscriptions model is ideal when compares to call a server method each 5 seconds or so.
When you don't want reactive updates, simply pass the flag reactive:false in your find() query.
Methods are used when you want, for example, to return the results on an aggregation (because meteor doesn't support reactivity for aggregations), to get updates for unsupported operator ($where is not supported yet), etc.
Usually the bottlenecks exists in the application design/architecture.

Implementing a robust and efficient RPC system

I need to have a server which is able to call functions on the client. I always used RPC's in different networking game API's but I never implemented it by myself.
How would I do it?
My naive approach would be:
connect client to the server:
server
fn update_position_client(){
unique_id = 1;
send.to_client(unique_id);
}
client
while recv_messages {
if id == 1
update_position();
}
Is this how I would do it?
This works if you only have a few messages that you want to send, and if the data basically known. To be more robust, you would want to have the ability to dynamically add/remove messages that can be called, and figure out how to look up the methods to be called when RPC is called.
Assuming you want this to be completely transparent to the user, what typically happens in this case is that when the a message is sent, the RPC library will wait until there's a response back. Assuming bi-directional capabilities, what normally happens is that there's a single thread that listens for data. If an RPC message comes in, this thread will figure out what to do with the message, i.e. what method to call in your(local) address space and with what parameters you want to call it with. When you send an RPC message out, the thread that you sent the message out on is blocked(probably with a semaphore) until the return message comes back, at which point your local thread is unblocked and allowed to continue.
A Linux-specific RPC library you could look at would be DBus.

Where should Meteor.methods() be defined?

http://docs.meteor.com/#meteor_methods
I have tried it in publish.js in my server folder.
I am successfully calling Meteor.apply and attempting the server call from the client. I always get an undefined response.
Calling Meteor.methods on the server is correct. That will define remote methods that run in the privileged environment and return results to the client. To return a normal result, just call return from your method function with some JSON value. To signal an error, throw a Meteor.Error.
On the client, Meteor.apply always returns undefined, because the method call is asynchronous. If you want the return value of the method, the last argument to apply should be a callback, which will be passed two arguments: error and result, in the typical async callback style.
Is your server code actually getting called? You can check that by updating the DB in the method and seeing if the client's cache gets the new data, or calling console.log from inside the method body and looking at the output of the "meteor" process in your terminal.
There are several places I can define my Meteor.methods() (with pro's and con's):
On the server only - when the client calls the method, it'll have to wait for the server to respond before anything changes on the client-side
On the server, and uses a stub on the client - when the client calls the method, it will execute the stub method on the client-side, which can quickly return a (predicted) response. When the server comes back with the 'actual' response, it will replace the response generated by the stub and update other elements according.
The same method on both client and server - commonly used for methods dealing with collections, where the method is actually a stub on the client-side, but this stub is the same as the server-side function, and uses the client's cached collections instead of the server's. So it will still appear to update instantly, like the stub, but I guess it's a bit more accurate in its guessing.
I've uploaded a short example here, should you need a working example of this: https://gist.github.com/2387816
I hope some will find use of this addition, and this doesn't cloud the issue that methods are primarily intended to run on the server as debergalis has explained.
Using Meteor.methods() on the client is useful too. (look for "stub" in the Meteor.call() section too...)
This allows the client to (synchronously) simulate the expected effect of the server call.
As mentioned in the docs:
You use methods all the time, because the database mutators (insert,
update, remove) are implemented as methods. (...)
A separate section explaining use of stubs on the client might ease the understanding of methods calls on the server.

node.js asynchronous initialization issue

I am creating a node.js module which communicates with a program through XML-RPC. The API for this program changed recently after a certain version. For this reason, when a client is created (createClient) I want to ask the program its version (through XML-RPC) and base my API definitions on that.
The problem with this is that, because I do the above asynchronously, there exists a possibility that the work has not finished before the client is actually used. In other words:
var client = program.createClient();
client.doSomething();
doSomething() will fail because the API definitions have not been set, I imagine because HTTP XML-RPC response has not returned from the program.
What are some ways to remedy this? I want to be able to have a variable named client and work with that, as later I will be calling methods on it to get information (which will be returned via a callback).
Set it up this way:
program.createClient(function (client) {
client.doSomething()
})
Any time there is IO, it must be async. Another approach to this would be with a promise/future/coroutine type thing, but imo, just learning to love the callback is best :)

Resources