Watch out for callback data dependencies and closures

Functions defined on the server that have their proxy property set to true (e.g. by being in a script block with runat="server-proxy", or by directly setting their proxy property) are automatically made available in the page served to the browser. The original function definitions are stored on the server for use during callbacks. So are any functions on the same page that they could have called: basically any functions that were not explicitly set to runat="server-nocache".

But when you make the callback, and your called function executes on the server, you should make sure that whatever your function needs to run successfully is available: it can call the other server-side functions that were defined on the page (except for non-cached ones), and it can access databases, files, and certain session variables, but it should not rely upon closures to be available...

What are closures? Say you have the following bit of server-side code: Both saveData and readData get the name of the file from a single external variable, filename, so they're guaranteed to read and write to the same file. The filename variable creates a closure: saveData and readData save references to filename, and would have access to filename even when they are called from some context in which filename were not directly available (which is not the case here).

So what's wrong with this? During a callback, only functions are guaranteed to be made available again, not data. E.g. if the callback is handled by a different Jaxer instance in a pool of Jaxer processes, that Jaxer would recreate the functions cached for that page from the database, but would not recreate the filename variable or its value.

What's a good way to get around this limitation? One way is to use another function to return common data. This has other advantages, e.g. you could later change the function to get the data dynamically from a session variable or a database or a web service.