-
Notifications
You must be signed in to change notification settings - Fork 373
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
Fix performance issues with JRuby #647
Conversation
It's hard to say for sure, but your tests may be failing in
I'd check each of those, see if that helps fix things. |
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.
I really like the simple approach here, and what you have should be backwards compatible from what I can tell. Left a question regarding the 'connection search' logic you had.
Although I'm not a fan of having to search through Rails connections every time an event is done, the Rails guys said it's unlikely to have a big performance impact. We'll probably want to keep an eye on this to verify this is okay. At least we're getting rid of _id2ref
so that's a plus.
Let's try to get these tests passing. I think we can give it one last review and probably merge it if we can.
conn = | ||
connection || ::ActiveRecord::Base | ||
.connection_handler | ||
.connection_pool_list |
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.
Will this iterate over all ActiveRecord connections? Regardless if they were made with ActiveRecord::Base.establish_connection
, or from a class that inherits from ActiveRecord::Base
? Just want to make sure connections configured in a legitimate way for Rails don't slip through the cracks.
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.
yep all there is connected (in whatever way) with AR
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.
I think, but I'm not sure, that it's all connections in the current process, because here's how connection_pool_list
is defined (at least in Rails 4.2):
def connection_pool_list
owner_to_pool.values.compact
end
and here's how owner_to_pool
is defined:
def owner_to_pool
@owner_to_pool[Process.pid]
end
If I understand well (and I'm absolutely not sure of that) this line of code: @owner_to_pool[Process.pid]
, it says that it takes the pools for the current process only.
Which means that for a multi-processes runtime (like Puma with workers or Unicorn) the number of connections should be fairly low (at least, it's my assumption. I know that AR is by default configured to use 5 connections, IIRC)
And for a multi-threaded runtime (like Puma with JRuby) it means all the connections but it seems that in this case AR uses only one connection per thread (maybe per db) which is again fairly small (I think 😕).
WDYT ?
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.
you got that right: one connection per thread
per Model.establish_connection (class_to_pool
) - which usually means a different DB connection.
Process.pid
is really only due MRI - not much forking under JRuby.
under a multi-process (MRI) connections are low (usually ~1 since one process == one request), under a GIL-less runtime it can go as high as the server handles concurrent requests.
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.
@kares Clever that since its segmented by process/thread that it makes the pool to be searched much smaller. I think this is only problematic if the AR event is generated from one thread, and handled in another, which would cause it to search the wrong pool. I can't really think of how that would happen here.
@guizmaii Okay, so I guess my last concern is, does this work with Rails 3.0 - latest? We have broken tests in this PR so its hard to tell. If we can get the build passing, it will run the Rails tests for these different versions, and that would be good enough to tell me whether this condition has been satisfied.
I think I prefer your implementation here, but just for reference, I did open a couple of branches that's an alternative implementation of this.
It might be a good idea to compare the performance of each of these, see if there's a significant difference or not. But I'm tempted to keep yours if it's similar or better in performance since what you have is simpler. For now, let's get your tests passing. |
I still have to look at your alternative solutions but the second link you propose redirect to this issue. IMO, it's not the correct link ;) |
@guizmaii Whoops, forgot to fill in the link. Fixed now. |
Closed in favor of #649 |
@guizmaii Per #661 we should probably re-open this and implement it over what I had in #649. That PR works by itself, but it has too many incompatibilities with 3rd party libs that serialize |
I couldn't push to this branch (permission was denied) so I opened up #662 instead. |
Fix #640