-
Notifications
You must be signed in to change notification settings - Fork 5.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Session hooks #1611
Session hooks #1611
Conversation
of connections can be closed without waiting for the close callbacks on one connection to return before closing the other connections. Underscore internal Session field `_closeCallbacks`. Update comment to explain the cause of the problem requiring the use of `Meteor.bindEnvironment` with Meteor's public API.
|
||
// sessionId -> SessionHandle | ||
var sessionHandles = {}; | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note an alternative is if Meteor.server had an API to get the session from a session id, accounts wouldn't need to maintain its own mapping here.
`closeSessionsForTokens` doesn't need to clone `sessionsByLoginToken` because `onClose` callbacks are deferred. Simplify `closeTokensForUser` by using `_.pluck`.
@@ -1,3 +1,70 @@ | |||
// token -> list of session ids |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Code organization for easy reading: this should go in the "RECONNECT TOKENS" or "TOKEN EXPIRATION" section, not at the top of the file.
This is looking good! Some comments inline. Also, can you please add some docs for the new public APIs? I think users will be really excited to use them! |
Poll instead of using Deps.autorun in server test. When polling the client connection, tests don't have a chance to disconnect before the stream client automatically reconnects, so add an option to disable retries for testing. Callers of `Meteor.bindEnvironment` often have the `onException` argument print the exception stack trace. To allow for less code duplication, let the argument be a string providing the context (e.g. "connection closed callback"), and then on an exception print the context and the exception stack trace.
{{#dtdd name="onClose" type="Function"}} | ||
Register a callback to be called when the session is closed. | ||
|
||
When session reconnections are implemented, the client closing the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe condense both sections on "when there is session reconnect" into a single {{note}}
?
session id. Make _sessionData available in a nested method invocation on the server.
Document `Meteor.onConnection` instead of `Meteor.server.onConnection`. Condense sections about when there is a session reconnect into a single {{note}}. Document the `stop` handle returned by `onConnect`. Document `this.session` in Meteor.methods section.
the onConnection callback.
at the same time.
"session handle".
fn = Meteor.bindEnvironment( | ||
fn, | ||
function (err) { | ||
Meteor._debug( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ditto String form.
Pull out the session object into its own documentation section.
when the error callback only needs to print the exception. Replace unsafe references to `err.stack` with `err && err.stack || err`. This avoids throwing a secondary exception if the original exception in `err` isn't an object (`throw(null)` and `throw(undefined)` are legal in JavaScript), and also displays the error object if the stack trace wasn't included.
Add tests to check that account data is cleaned up after a session closes. Make `establishConnection` available to account tests. Remove code duplication between `poll` (now called `simplePoll`) and the async_multi `pollUntil`.
Looks great! Will merge. Nice work. |
Hey guys, just read up a little on this (not thoroughly). It looks like methods and publish functions are getting access to a server side session object that represents the DDP session? This is completely different to the Session on the client side, right? If I've understood correctly, would this server side session object be a good place to hold the client's accepted languages, hostname, user agent, IP address etc? (for use within methods and publish functions) |
Yup! |
That's pretty damn exciting. Seems like a very nice approach. |
Hrm. I ran our many-browser tests and this patch seems to cause issues. http://test-results-pr-1611-2-20131128-001934.meteor.com/ I've seen this pattern of failures (mostly accounts emails tests, some changing userid reruns subscriptions) before. In that case it was triggered by something closing the main DDP connection between the client and the server and it reconnecting mid-test. Could something in the new tests be causing a reconnect mid-test run? I'll look into this early next week, unless you beat me to it @awwx =) |
That's strange. The hash-login-tokens PR does add some extra steps to the client login token tests that could be doing something, but the session-hooks tests are all server-only (making a DDP connection from the server to the server), so I don't know why it would be affecting the main DDP connection between the client and server. Unless of course one of the server tests is closing the main connection accidentally :) But I didn't see anything. I'd need a way to reproduce this to investigate myself... are the many-browser tests something I could run? Or are the many-browser tests running multiple tests in parallel, and perhaps I'd be able to see the same thing if I run the unit tests in a loop from multiple browser windows? |
@awwx unfortunately, I can't give you access to the automated test repo. It's a private repo and has API keys and account details. But I think it should replicable without the cross-browser component -- I don't think the individual browsers make much of a difference. Deploying a test site (meteor test-packages --deploy foo.meteor.com) and pointing many browser tabs at it will hopefully do the trick. |
@n1mmy @timhaines Unless I'm missing it, I think we still don't have the actual plumbing to get the IP/headers/etc. associated with a session, though session handles will certainly be part of that plumbing. Should we add that in? Client IP seems like a good thing to add (and is part of the current login hooks design: https://meteor.hackpad.com/Login-hooks-design-notes-o0809sK58jX), but I'm not sure if HTTP headers is an elegant thing to have on a session, because it kind of intermingles DDP with HTTP. Maybe this is just a matter of naming the field nicely (like |
@estark37 re: "not sure if HTTP headers is an elegant thing to have on a session" - you'd agree that it's beneficial to have at least a subset of the headers available from within methods and publish functions though right? |
@timhaines Absolutely! Headers, query parameters, all sorts of things that are very HTTP-ish... I think it's just a matter of figuring out the right way to expose it that doesn't tie the concept of a DDP session to HTTP. |
Correct.
Right, I suspect what we want is to have information derived from the headers (instead of necessarily the headers themselves). For example, if the client is connecting to a load balancer which is forwarding connections to the Meteor server, the IP address of the client is available in the X-Forwarded-For header. On the other hand, if the client is connecting to the Meteor server directly, the X-Forwarded-For header must be ignored (since otherwise the client could forge it). So ideally the session would get the "client IP" supplied to it, without the developer using the session having to worry about how to dig it out of the headers etc. |
@n1mmy oops, http://test-results-pr-1611-2-20131128-001934.meteor.com/ got cleared. Do you happen to remember which test was failing? I suspect running tests from multiple browser tabs (as opposed to multiple browsers) won't work because the accounts-password client tests login and logout. Firefox however has the option to run with different user profiles, so it's possible to run multiple instances of Firefox on a computer. I tried running a bunch of simultaneous tests using both test-in-console and using multiple Firefox instances. I am seeing an
|
@n1mmy ack, I wasn't in the session-hooks branch :) Let me try again... |
@n1mmy when you run the many-browser tests, how many browsers are you typically running at once? Are you testing all packages? |
@n1mmy OK, this time I managed to checkout the session-hooks branch... :-) I ran 10 simultaneous phantomjs instances in a loop against test-in-console; and then 4 simultaneous instances of Firefox with test-in-browser hacked to keep running tests over and over; both running against accounts-base, accounts-password, and livedata tests. No luck, I do get the expireTokens error message occasionally but no actual test failures. Without a successful reproduction I'm not getting much forwarder... |
Great stuff! Two questions:
I completely agree that browser headers and IP should be exposed in some way, if HTTP was used for DDP. Because this would be really useful for example to determine the language of the user, timezone, geo location and so on. |
Merged in b5cd66d |
@mitar: yes, we'll have login hook eventually too. design ongoing at https://meteor.hackpad.com/Login-hooks-design-notes-o0809sK58jX. Also client IP eventually. We still need to figure out how to make this available in more places, eg, allow / deny. Unfortunately, allow/deny callbacks take explicit positional arguments which make it hard to extend. We might want to make them take some sort of options hash to allow for extensibility. |
@n1mmy: You could just provide |
Unfortunately, the name |
Oh, true. :-( But the name is not so important, the concept of having a function you call in a similar fashion as BTW, but they are not so different concepts, no? On the client, |
This seems super useful. Time to rewrite https://github.com/mizzao/meteor-user-status... However, the previous method of tracking connections allowed for reading the IP address. How can we do this with the |
Add Meteor.server.onConnection API.
Move handling of login tokens from livedata to accounts.