I am building (yet another) RPC client/server for calling methods between a browser and a Node.js server. (My reason for this is that I already have streams and serialization taken care of by BinaryJS, and there is no solid solution that I've already seen that simply uses object streams for RPC. rpc-stream seemed like a good fit, but it only allowed for a single callback and was inflexible in parameter ordering and what not.)
I'm having a hard time figuring out how to implement callbacks. Suppose on the client, I call some code like this:
rpcClient.someRemoteMethod('parameter1', 'parameter2', function callback1 () {
// callback1
}, function callback2 () {
// callback2
});
I would expect the client to then create a message to the RPC server along these lines:
{
method: 'someRemoteMethod',
parameters: ['parameter1', 'parameter2', /* something to reference callback1 */, /* something to reference callback2 */]
}
On the server end, the RPC server could do something like:
wrappedObject[data.method].apply(parameters);
How do I handle the callbacks though? Obviously I need to create some function on the fly that then sends a set of parameters back to the other end, as well as shuffles the return value back to the server. This isn't too hard... I can have a set of IDs or something to track functions in a collection. However, how long do I keep one of these dynamically created callbacks around on the server end?
If I create one of these callback functions, how do I know that all references to it have been removed, other than the reference in my collection of callbacks? I don't want to get into a situation where I have millions of callbacks in a collection sitting around just because other code might call them some time.
For what it's worth, Socket.IO had a similar problem a couple years ago. I don't know if it still applies.
Related
In Node.js, can it happen that when different properties of a global object are written at the same time (with a socket.io request), one of the properties retains its original value?
`
var rooms = {
a: {
move: 1
},
b: {
move: 2
}
};
// it's called same time from different client with different room id
socket.on('onmove', function(data) {
var room = rooms[data.room_id];
room.move = data.move;
});
`
I tried to testing, but did not collide with each other.
However, I have an online game where the anomalies point to this.
The question is, is this theoretically possible? How are properties overwritten? Does one have an effect on the other?
Nodejs runs your Javascript in a single thread so no two requests are actually executing your Javascript at the exact same moment in time. So, the code you show, all by itself, will not be susceptible to a race condition.
The question is, is this theoretically possible?
No, not with just the code you show. The move event handler will run to completion before any other requests or events can get called.
How are properties overwritten? Does one have an effect on the other?
No. Assigning to one property does not affect other properties.
That said, there are certainly concurrency-related things to be aware of in nodejs, particularly if a request handler is doing something asynchronous. This is because, while it's waiting for some asynchronous completion callback to be called, other requests can run, change state, etc... So, if one request handler grabs some state, then does something asynchronous and expects that state not to change while it's waiting for the asynchronous callback to be called, then it could lead to concurrency issues because other request handlers can run during that time and can affect server-side state.
Plus, there are many database operations that need to be coded carefully to avoid concurrency issues since two requests could be trying to make conflicting changes to the database or one request handler could grab some data, modify and write it back while another request handler is doing the same thing causing one request's changes to get overwritten.
So, if you suspect that this code is somehow involved in a concurrency issue, then I'd suggest you disclose a lot more related code so we can see if the way you've written the rest of the related code could lead to concurrency issues.
Please feel free to sort me out if this is a redundant question. (I have searched as much as I can bear before asking)
I am desperately trying to understand the life cycle of the request/response objects.
Consider the following skeleton code:
app.get('/', function(req, res) {
var setCookie = function(err, idCookie) { //callback after cookieSearch in DB
// ... do something with the result of findCookieInDatabase() (handle error, etc.);
res.sendfile('index.html');
}
var cookie = parseCookie(req.get('Cookie')); //parse and format cookie
findCookieInDatabase(cookie, afterCookieSearch); //tries to find cookie is DB
// .. do some content return stuff, etc.
}
(Please note that the original code does a whole lot more, such as checking if 'Cookie' even exists etc.)
I uderstand that req and res objects are created and must be at some point garbage collected. (One would hope)
When findCookieInDatabase() is called with setCookie as a parameter I'm assuming that setCookie is just a string (containing the function) at the time and does not get parsed nor executed until the callback(setCookie) statement is encountered in findCookieInDatabase().
I also understand that I might be utterly wrong with the above assumption which would be due to my lack of understanding the guts of javascript callbacks. (I have searched a lot on this also but all I could find is endless tuts on how to use callbacks. Nothing on what's under the hood)
So the question is this:
How does javascript (or node.js) know how long to keep 'res' alive and when is it ok to garbage collect it?
Does the line res.sendfile in setCookie actually act as an active reference because it is invoked through findCookieInDatabase()?
Does javascript actually keep track of all the references and keeps req and/or res alive so long as any part of any called/callback-ed/things are alive?
Any help greatly appreciated. Thanks for reading.
There's a lot going on with your code -- and your assumptions -- that indicates to me that you should study some JavaScript fundamentals. I would recommend the following books:
Speaking JavaScript, by Axel Rauschmayer
JavaScript: The Good Parts, by Douglas Crockford (please note: I don't think everything that Douglas Crockford says is golden, but I would consider this book required reading for aspiring JavaScript programmers)
Learning Node, by Shelley Powers
And of course my own book, Web Development with Node and Express. Okay, now that I've got all the reading material out of the way, let me try to get to the heart of your question.
When Node receives an HTTP request, it creates the req and res objects (which begin their life as instances of http.IncomingMessage and http.ServerResponse respectively). The intended purpose of those objects is that they live as long as the HTTP request does. That is, the client makes an HTTP request, the req and res objects are created, a bunch of stuff happens, and finally a method on res is invoked that sends an HTTP response back to the client, and at that point the objects are no longer needed.
Because of Node's asynchronous nature, there could be multiple req and res objects at any given time, distinguished only by the scope in which they live. This may sound confusing, but in practice, you never have to worry about that: when you write your code, you write it as if you were always ever dealing with one HTTP request, and your framework (Express, for example), manages multiple requests.
JavaScript does indeed have a garbage collector, which eventually deallocates objects after their reference count drops to zero. So for any given request, as long as there's a reference to the req object (for example), that object will not be deallocated. Here's a simple example of an Express program that always saves every request (this is a terrible idea, by the way):
var allRequests = [];
app.use(function(req, res, next) {
allRequests.push(req);
next();
});
The reason this is a terrible idea is that if you never remove objects from allRequests, your server will eventually run out of memory as it processes traffic.
Typically, with Express, you'll rely on asynchronous functions that invoke a callback once they've done their work. If the callback function has a reference to the req or res objects, they will not be deallocated until the asynchronous function completes and the callback executes (and all other references are out of scope, naturally). Here's a simple example that just generates an artificial delay:
app.get('/fast', function(req, res) {
res.send('fast!');
});
app.get('/slow', function(req, res) {
setTimeout(function() {
res.send('sloooooow');
}, 3000);
});
If you navigate to /slow, your browser will spin for 3 seconds. In another browser, if you access /fast a bunch of times, you'll find that it still works. That's because Express is creating a req and res object for each request, none of which interfere with each other. But the res object associated with the /slow request is not deallocated because the callback (which is holding a reference to that instance) hasn't executed.
At the end of the day, I feel like you're overthinking things. It's good to understand the fundamentals, certainly, but for the most part, reference counting and garbage collection in JavaScript is not something you have to think about or manage.
I hope this helps.
Say I am using a pub/sub pattern with highly modularized code. When a function in one module sends out a 'publish', how I do make clear what functions in other modules are subscribing to that trigger?
For example:
// In module 1
function foo(data) {
publish("trigger", data);
}
// In module 2
function bar(data) {}
subscribe("trigger", bar);
// In module 3
function baz(data) {}
subscribe("trigger", baz);
After reading module 1 and seeing that a 'publish' is been sent out, how would someone know where to look in my code for the subscribed callbacks?
An obvious solution might be to comment what modules contain functions that subscribe to the trigger, but that seems an impractical solution when dealing with a large number of publishes / subscribers.
I feel like I'm not fully understanding how to use the pub/sub pattern, since to me, the pattern seems to have no transparency whatsoever regarding function chains.
EDIT
My question pertains to making my code clear and easy to understand for someone reading my source code. I understand that during runtime, I could programmatically find the list of stored subscribers, by access the array of stored callbacks. But that does nothing for making my raw source code more easily understood.
For example, I current use a pattern like this:
// Main Controller Module
function foo(data) {
module2.bar();
module3.bar();
}
// In module 2
function bar(data) {}
// In module 3
function baz(data) {}
For starters, what is the proper term for this module? I thought it was a 'mediator' pattern, but looking here, it seems a mediator pattern is more like what I thought a pub/sub was?
With this pattern I feel the flow of my code is completely transparent. The reader doesn't need to dig around to find out what functions in other modules foo() might call.
But with the pub/sub pattern, once I send out the publish from foo(), it's like the reader has to somehow find the modules where the subscribed functions are.
But of course the downside of the above pattern is heavy dependency: module 1 needs both module 2 and 3 injected before it can call bar() and baz().
So I want to adopt the loose coupling of the pub/sub pattern, but I also want to keep the function flow transparency that the above pattern gives me. Is this possible? Or is this just the inherent trade-off of a pub/sub pattern?
To Mod:
Please delete question. I wrote this question poorly and would like to re-ask the question in a clearer manner. thanks.
I thought the whole idea of publish subscribe or mediator is to loosely couple objects. Object1 doesn't need to know what happens who does what it is only concerned doing it's own thing and notifying whoever is interested that it's done doing what it does.
I register listeners only in a controller class and not all over the code. When the controller needs to do add or remove listeners then break up your process in steps that will inform the controller first (create appropriate events for it).
For example:
We fetch data with XHR.
Based on the data we create processors, processors are created with factory.
Processors process data.
Data is displayed.
Process is finished.
In your controller you could have:
var Controller = {
//fetch information and display it
fetch : function(paramObj){
var subscribeIds = [];
//to have xhr listen to fetch can be done in an init function
// no need to add and remove every time but make a note here
// that it's registered in init and part of this process
subscribeIds.push(Mediator.subscribe(xhr.fetch,"fetch"));
//xhr will trigger dataFetched
subscribeIds.push(Mediator.subscribe(Controller.initProsessor,"dataFetched"));
//Controller will trigger displayFetched
subscribeIds.push(Mediator.subscribe(dom.displayFetched,"displayFetched"));
subscribeIds.push(Mediator.subscribe(Controller.displayedFetched,"displayedFetched"));
paramObj.suscribeIds = subsribeIds;
Mediator.trigger("fetch",paramObj);
},
initProsessor : function(paramObj){
var processor = Processor.make(paramObj.data.type);
paramObj.html = processor.process(data);
Mediator.trigger("displayFetched",paramObj);
},
displayedFetched : function(paramObj){
//You can decide the process is done here or take other steps
// based on paramObj
//You can unsubscribe listeners or leave them, when you leave them
// they should not be registered in the fetch function but rather
// in an init function of Controller with comments saying
// basic fetch procedure
Controller.cleanupListeners(paramObj.subscribeIds);
},
cleanupListeners : function(listenersIds){
Mediator.unSubscribe(listenersIds);
}
}
The code looks more complicated than needs to be. Someone looking at it may think why not let XHR make a Processor instance and tell it to process? The reason is that the Controller literally controls the flow of the application, if you want some other things to happen in between you can add them. As your application grows you'll add more and more processes and sometimes re factor functions to do less specific things so they can be better re used. Instead of possibly having to change your code in several files you now only re define the process(es) in the Controller.
So to answer your question as to where to find the listeners and where events are registered: in the controller.
If you have a single Mediator object you can have it dump listeners at any time, just write a dump method that will console.log the event names and functions.toString().
I am currently implementing a graph visualisation tool using lift on the server side and d3 ( a javascript visualisation framework) for all the visualisation. The problem I have is that in the script I want to get session dependent data from the server.
So basically, my objective is to write lift-valid ajax callbacks in a static js script.
What I have tried so far
If you feel that the best solution is one that I already tried feel free to post a detailed answer telling me how to use it exactly and how it completely solves my problem.
Write the ajax callback in another script using lift and call it from the main script
This solution, which is similar to a hidden text input is probably the more likely to work. However it is not elegant and it would mean that I would have to load a lot of scripts on load, which is not really conveniant.
This seems to be one of the prefered solutions in the lift community as explained in this discussion on the mailing list.
REST interface
Usually what one would do to get data from a javascript function in lift is to create a REST interface. However this interface will not be linked to any session. This is the solution I got from my previous question: Get json data in d3 from lift snippet
Give function as argument of script
Another solution would be to give the ajaxcallback as an argument of the main script called to generate my graph. However I expect to have a lot of callbacks and I don't want to have to mess with the arguments of my script.
Write the whole script in lift and then serve it to the client
This solution can be elegant, however my script is very long and I would really prefer that it remainss static.
What I want
On client side
While reviewing the source code of my webpage I found that the callback for an ajaxSelect is:
<select onchange="liftAjax.lift_ajaxHandler('F966066257023LYKF4=' + encodeURIComponent(this.value), null, null, null)" name="F96606625703QXTSWU" id="node_delete" class="input">
Moreover, there is a variable containing the state of the page in the end of the webpage:
var lift_page = "F96606625700QRXLDO";
So, I am wondering if it is possible to simulate that my ajaxcall is valid using this liftAjax.lift_ajaxHandler function. However I don't know the exact synthax to use.
On server side
Since I "forged" a request on client side, I would now like to get the request on client side and to dispatch it to the correct function. This is where the LiftRules.dispatch object seems the best solution: when it is called, all the session management has been made (the request is authentified and linked to a session), however I don't know how to write the correct piece of code in the append function.
Remark
In lift all names of variables are changed to a random string in order to increase the security, I would like to have the same behavior in my application even if that will probably mean that I will have to "give" the javascript these values. However an array of 15 string values is still a better tradeoff than 15 functions as argument of a javascript function.
Edit
While following my research I found this page : Mapping server functions to client actions which somehow explains the goal of named functions even if it stil didn't lead me to a working solution.
Quick Answer
Rest in Lift does not have to be stateless. If you register your RestHelper with LiftRules.dispatch.append, then it will be handled statefully and Session information will be available through the S object as usual.
Long Answer
Since you seem interested, and it's come up on SO before, here's a more detailed explanation of how server-side functions are registered and called in Lift. If you haven't worked with Lift for some time, look away. What follows should not in any way be used to evaluate Lift or its complexity. This is purely library developer level stuff and a majority of Lift users go about their development blissfully unaware of it.
How it works
When you create stateful callbacks, typically by using the methods within the SHtml object, what you are really doing is registering objects of type S.AFuncHolder within the context of the users session, each with a unique ID. The unique ID that was generated during this process is what you're seeing when you come across a pattern like F96606625700QRXLDO. When data is submitted, via form post, ajax, or whatever, Lift will check the request for these function ids and execute the associated function if they exist. There are several helpers that provide more specific types of AFuncHolder, like S.SFuncHolder (accepts a single string query parameter) and S.BinFuncHolder (parameter is multipart form data) but they all return Any and behind the scenes Lift will collect those return values to create the proper type of response. A JsCmd, for instance, will result in a JavaScriptResponse that executes the command. You can also return a LiftResponse directly.
How to use it
AFuncHolders are registered using the S.fmapFunc method. You'd call it like this
S.fmapFunc(SFuncHolder({ (str: String) =>
doSomethingAwesomeWithAString(str)
}))(id => <input type="text" name={id} value=""/>)
The first parameter is your function, wrapped in the proper *FuncHolder type and the second parameter is a function that takes the generated id and outputs something. The something that gets output is what you will include on the page. It should somehow result in the id being sent to the server as a query parameter so that your function is executed.
Putting it all together
You could use the above to make your own Ajax calls, but when Lift makes an ajax call there are a few other considerations:
1) Most browsers only allow so many simultaneous connections to a given domain. Three seems to be the magic number.
2) AFuncHolders will often close over the scope of the snippet they are contained within and if multiple ajax requests are handled at once, each in its own thread, bad things can happen.
To combat these issues, the liftAjax.lift_ajaxHandler function queues each ajax request, ensuring that only one at a time is sent to the server.
The drawback to this approach is that it can make it difficult to make an Ajax call where the result needs to be passed to a callback. JQuery autocomplete, for instance, provides a callback function when input changes that accepts a list of matches. If you are manually calling LiftAjax.lift_ajaxHandler though, you can provide your own callback functions for success & error and I would recommend that you look at the source of those functions in your browser for more information on how they work.
There's actually more to it, like how Lift restores RequestVars on ajax callbacks (which is where the lift_page comes in, but that's about all I'm prepared to explain over coffee on a Saturday morning :)
Good luck with your app!
I have an interesting situation that my usually clever mind hasn't been able to come up with a solution for :) Here's the situation...
I have a class that has a get() method... this method is called to get stored user preferences... what it does is calls on some underlying provider to actually get the data... as written now, it's calling on a provider that talks cookies... so, get() calls providerGet() let's say, providerGet() returns a value and get() passes it along to the caller. The caller expects a response before it continues its work obviously.
Here's the tricky part... I now am trying to implement a provider that is asychronous in nature (using local storage in this case)... so, providerGet() would return right away, having dispatched a call to local storage that will, some time later, call a callback function that was passed to it... but, since providerGet() already returned, and so did get() now by extension to the original called, it obviously hasn't returned the actual retrieved data.
So, the question is simply is there a way to essentially "block" the return from providerGet() until the asychronous call returns? Note that for my purposes I'm not concerned with the performance implications this might have, I'm just trying to figure out how to make it work.
I don't think there's a way, certainly I know I haven't been able to come up with it... so I wanted to toss it out and see what other people can come up with :)
edit: I'm just learning now that the core of the problem, the fact that the web sql API is asychronous, may have a solution... turns out there's a synchronous version of the API as well, something I didn't realize... I'm reading through docs now to see how to use it, but that would solve the problem nicely since the only reason providerGet() was written asychronously at all was to allow for that provider... the code that get() is a part of is my own abstraction layer above various storage providers (cookies, web sql, localStorage, etc) so the lowest common denominator has to win, which means if one is asychronous they ALL have to be asychronous... the only one that was is web sql... so if there's a way to do that synchronously my point become moot (still an interesting question generically I think though)
edit2: Ah well, no help there it seems... seems like the synchronous version of the API isn't implemented in any browser and even if it was it's specified that it can only be used from worker threads, so this doesn't seem like it'd help anyway. Although, reading some other things it sounds like there's a way to pull of this trick using recursion... I'm throwing together some test code now, I'll post it if/when I get it working, seems like a very interesting way to get around any such situation generically.
edit3: As per my comments below, there's really no way to do exactly what I wanted. The solution I'm going with to solve my immediate problem is to simply not allow usage of web SQL for data storage. It's not the ideal solution, but as that spec is in flux and not widely implemented anyway it's not the end of the world... hopefully when its properly supported the synchronous version will be available and I can plug in a new provider for it and be good to go. Generically though, there doesn't appear to be any way to pull of this miracle... confirms what I expected was the case, but wish I was wrong this one time :)
spawn a webworker thread to do the async operation for you.
pass it info it needs to do the task plus a unique id.
the trick is to have it send the result to a webserver when it finishes.
meanwhile...the function which spawned the webworker sends an ajax request to the same webserver
use the synchronous flag of the xmlhttprequest object(yes, it has a synchronous option). since it will block until the http request is complete, you can just have your webserver script poll the database for updates or whatever until the result has been sent to it.
ugly, i know. but it would block without hogging cpu :D
basically
function get(...) {
spawnWebworker(...);
var xhr = sendSynchronousXHR(...);
return xhr.responseTEXT;
}
No, you can't block until the asynch call finishes. It's that simple.
It sounds like you may already know this, but if you want to use asynchronous ajax calls, then you have to restructure the way your code is used. You cannot just have a .get() method that makes an asynchronous ajax call, blocks until it's complete and returns the result. The design pattern most commonly used in these cases (look at all of Google's javascript APIs that do networking, for example) is to have the caller pass you a completion function. The call to .get() will start the asynchronous operation and then return immediately. When the operation completes, the completion function will be called. The caller must structure their code accordingly.
You simply cannot write straight, sequential procedural javascript code when using asynchronous networking like:
var result = abc.get()
document.write(result);
The most common design pattern is like this:
abc.get(function(result) {
document.write(result);
});
If your problem is several calling layers deep, then callbacks can be passed along to different levels and invoked when needed.
FYI, newer browsers support the concept of promises which can then be used with async and await to write code that might look like this:
async function someFunc() {
let result = await abc.get()
document.write(result);
}
This is still asynchronous. It is still non-blocking. abc.get() must return a promise that resolves to the value result. This code must be inside a function that is declared async and other code outside this function will continue to run (that's what makes this non-blocking). But, you get to write code that "looks" more like blocking code when local to the specific function it's contained within.
Why not just have the original caller pass in a callback of its own to get()? This callback would contain the code that relies on the response.
The get() method will forward the callback to providerGet(), which would then invoke it when it invokes its own callback.
The result of the fetch would be passed to the original caller's callback.
function get( arg1, arg2, fn ) {
// whatever code
// call providerGet, passing along the callback
providerGet( fn );
}
function providerGet( fn ) {
// do async activity
// in the callback to the async, invoke the callback and pass it the data
// ...
fn( received_data );
// ...
}
get( 'some_arg', 'another_arg', function( data ) {
alert( data );
});
When your async method starts, I would open some sort of modal dialog (that the user cannot close) telling them that the request is in process. When the request finishes, close the modal in your callback.
One possible way to do this is with jqModal, but that would require you to load jQuery into your project. I'm not sure if that's an option for you or not.
This is ugly, but anyway I think the question is kindof implying an ugly solution is desired...
In your get function, serialize your query into a string.
Open an iframe, passing (A) this serialized query and (B) a random number in querystring to this iframe
Your iframe has some javascript code that reads the SQL query and number from its own querystring
Your iframe asynchronously begins running the query.
When your iframe query is asynchronously finished, it sends it, along with the random number to a server of yours, say to /write.php?rand=###&reslt="blahblahblah"
Write.php saves this info somewhere
Back in your main script, after creating and loading the iframe, you create a synchronous AJAX request to your server, say to /read.php?rand=####
/read.php blocks until the written info is available, then returns it to your main page
Alternately, to avoid sending the data over the network, you could instead have your iframe encode the result into a canvas-generated image that the browser caches (similar to the approach that Zombie cookie reportedly used). Then your blocking script would try to continually load this image over and over again (with some small network-generated delay on each request) until the cached version is available, which you could recognize via some flag that you've set to indicate it's done.