Skip to content

Use notification to ensure that lazy-loaded model classes have transactions#20818

Merged
rafaelfranca merged 1 commit intorails:masterfrom
jeremywadsack:use_transactional_fixtures_all_databases
Jul 17, 2016
Merged

Use notification to ensure that lazy-loaded model classes have transactions#20818
rafaelfranca merged 1 commit intorails:masterfrom
jeremywadsack:use_transactional_fixtures_all_databases

Conversation

@jeremywadsack
Copy link
Contributor

@jeremywadsack jeremywadsack commented Jul 9, 2015

See #17776

In Rails 4 config.eager_load was changed to false in the test environment. This
means that model classes that connect to alternate databases with
establish_connection are not loaded at start up. If use_transactional_fixtures
is enabled for tests, transactions are wrapped around the connections that have been
established only at the start of the test suite. So model classes loaded later
don't have transactions, causing data created in the alternate database not to
be removed.

This change resolves that by creating a new !connection.active_record
notification that gets fired whenever a connection is established. I then added
a subscriber after we set up transactions in the test environment to listen for
additional connections and wrap those in transactions as well.

@jeremywadsack
Copy link
Contributor Author

I'll dig into the travis issues. I'm not sure the cause because they are unrelated to anything I think I changed.

The postgres failure appears to have hung the test suite. I ran into a problem with a stack overflow on Mocha trying to set an expectation and this might be related to that. When I switched to mocha 1.1.0 I didn't have that problem, but that might affect lots of other things so I thought that should be a separate commit / PR. (BTW. Mocha 0.14.0 is now over two years old.)

@jeremywadsack jeremywadsack force-pushed the use_transactional_fixtures_all_databases branch from b8c669a to 109ba6d Compare July 19, 2015 19:56
@jeremywadsack
Copy link
Contributor Author

I think I have these fixed up. We'll see what Travis decides. I kept running into YAML issues but I have them on master too (I rebased to make sure), so it might be something in my rails-dev-box (although I checked that was up-to-date).

If this passes Travis, I can squash commits if you want. I left them separate to document the changes in the PR.

@jeremywadsack
Copy link
Contributor Author

Any thoughts as to how to get Travis to pick this up again? Travis says it doesn't run CI for branches that can't be merged without conflict, but GitHub says this branch is "up-to-date with the base branch" and I tested the merge on my dev box and there's no conflict for me. I'm not familiar with Travis so I don't know if there's something else I need to do to get it's attention.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We prefer to avoid using try inside of the rails codebase.

@sgrif
Copy link
Contributor

sgrif commented Oct 20, 2015

One minor nitpick. Please squash and rebase as well.

@maclover7
Copy link
Contributor

^^ Please squash and rebase.

@jeremywadsack jeremywadsack force-pushed the use_transactional_fixtures_all_databases branch from 109ba6d to b832a60 Compare January 10, 2016 19:54
@jeremywadsack
Copy link
Contributor Author

@maclover7: Done, thanks for the nudge.

Tried to do that in October but there were tons of conflicts I didn't understand. Those seem to have magically disappeared so this was easy (once I destroyed and rebuilt my rails-dev-box to get the latest Bundler and ruby).

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

While I think this use case is valid, I don't think we need to add this to the public API.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok. I removed the docs.

@jeremywadsack jeremywadsack force-pushed the use_transactional_fixtures_all_databases branch from b832a60 to 20dc67e Compare January 11, 2016 03:31
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I dont like rescue nil :/ , we should be explicit about error handling .

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@arthurnn Fixed and removed the assignment-in-conditional which I think is also discouraged in Rails style guide.

@rafaelfranca
Copy link
Member

r? @arthurnn it is related with your work with connections, could you take a look?

@jeremywadsack this is a clever solution and it is fine to me. Could you rebase it? I promise you it will be the last time.

@rails-bot rails-bot assigned arthurnn and unassigned sgrif Jul 13, 2016
@rafaelfranca rafaelfranca self-assigned this Jul 13, 2016
Copy link
Member

@rafaelfranca rafaelfranca Jul 13, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we add a ! prefix in the instrumentation name to say people that it should not be used in production?

 message_bus.instrument('!connection.active_record', payload) do

@jeremywadsack jeremywadsack force-pushed the use_transactional_fixtures_all_databases branch from 66d3852 to 7237cc3 Compare July 13, 2016 05:26
@jeremywadsack
Copy link
Contributor Author

@rafaelfranca Added the ! prefix and rebased on master. Just waiting on travis.

…hat lazy-

loaded model classes have their connections wrapped in transactions.

See rails#17776

In Rails 4 config.eager_load was changed to false in the test environment. This
means that model classes that connect to alternate databases with
establish_connection are not loaded at start up. If use_transactional_fixtures
is enabled, transactions are wrapped around the connections that have been
established only at the start of the test suite. So model classes loaded later
don't have transactions causing data created in the alternate database not to
be removed.

This change resolves that by creating a new connection.active_record
notification that gets fired whenever a connection is established. I then added
a subscriber after we set up transactions in the test environment to listen for
additional connections and wrap those in transactions as well.
@jeremywadsack jeremywadsack force-pushed the use_transactional_fixtures_all_databases branch from 7237cc3 to 31a8588 Compare July 13, 2016 06:35
@rafaelfranca rafaelfranca merged commit 9fcfb86 into rails:master Jul 17, 2016
kamipo added a commit to kamipo/rails that referenced this pull request Jul 17, 2016
Follow up to rails#20818.

`retrieve_connection` is passed `spec_name` instead of `klass` since rails#24844.
@arthurnn
Copy link
Member

arthurnn commented Aug 2, 2016

FYI 88cdecc

@jeremywadsack
Copy link
Contributor Author

@arthurnn Thanks for fixing that extra connection. I wasn't sure if the delay caused by the instrumentation would be a problem. Note then, that the method now returns nil because owner_to_pool[spec.name] has not been set when it returns. I didn't know if that was a problem, but if not then we can probably remove line 865.

@jeremywadsack jeremywadsack deleted the use_transactional_fixtures_all_databases branch August 2, 2016 18:32
kamipo added a commit to kamipo/rails that referenced this pull request Dec 18, 2019
Related rails#36456.

I grepped the code base by `git grep -n 'connection_id: '` then I found
extra `connection_id: object_id` which is added at rails#20818 but unused.

Actually the `connection_id: object_id` is not a connection's object_id
but a connection_handler's object_id, it is very confusing.

Since the `:connection_id` in an internal instrument is not used, we can
just remove the incorrect information.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants