On Friday, April 27, 2012 5:05:21 AM UTC-7, Rodrigo Rosenfeld Rosas wrote: > > Of course Rails console will have to delegate to IRB, Pry or other > interactive shell at some point. But none of them (including bin/sequel) > will load the Rails environment alone. For example, you won't have access > to the 'helper' method (or variable, not sure) inside a normal IRB or > sequel session. Also, they won't run the initializers, etc. > > So, I'd have to create my own console. This is not a great thing to do. > For example, if I wanted to create a gem for integrating Sequel to Rails, > this wouldn't be the right approach to take. Currently I would depend on > asking the Rails core team to add a hook that would allow me to call > "Console.start" inside a block and they accept it. >
Well, the current way Rails does it has some bad corner cases. In addition to the threading issues (discussed below): what if your app uses more than one database? From the looks of the Rails sandbox, only the default database is sandboxed. Another approach would be creating another command like "rails > sequel-console" aliased as "rails sc", but that is clearly a desperate > solution. > > But I guess there is another reason why ActiveRecord preferred the at_exit > approach. I guess that block will only run after all threads are finished > running. So, even if you start some thread in the console and changed the > database from there it would still rollback all changes. Particularly I > would be fine not to support such edge case, but maybe I won't be able to > convince them to add such a hook. I'll see. > I'm guessing you are wrong about that. Starting a new thread would probably give you a new connection which would not be inside a transaction. I'll leave it up to someone else to test that theory. The correct way to do such a sandbox in Sequel would be to use after_connect to ensure that all new connections were inside a transaction. This would not be difficult to add via a Sequel extension, and could work without changes to Rails (assuming the appropriate Railtie). Each spec is already running on its own transaction. I'm just trying to get > the before(:all) code to also run inside the outer-most transaction. > What you proposed was using a transaction around multiple specs, and having each spec run in it's own savepoint. That is not the same as running each spec in its own transaction. Savepoints are not the same as transactions. > I guess RSpec don't implement the around(:all) because maybe it will run > the after(:all) inside an at_exit block maybe for preventing running > threads side effects, but I'm just guessing. I didn't look at RSpec code > yet. > I haven't looked either. My expectation would be that around(:all) would run only around the all of the related specs (similar to: run_before(:all); run_all_related_specs; ensure run_after(:all)). > Note I think that may be a general problem with your idea of using a > transaction around all the specs and a savepoint for each individual spec. > > > Could you please elaborate on that? Would you suggest me another approach > (rather than DatabaseCleaner.truncate) for avoiding creating the same > records all over again for usage in some examples? > If there is a disconnection inside a spec, the connection would be removed from the pool. The next time a query was issued, a new connection would be created, and this wouldn't be inside a transaction block. If you use the block-based API, you don't need to worry about this, as it handles the situation correctly. > I have already explained you the reasons why I think transactions and > savepoints would be a better option. It would be much faster and I could > still have some unchanged data always set in the database instead of > recreating them in my specs. > Your suggestion is a hack to try to increase performance at the expense of reliability. Running each spec in its own transaction is far more reliable. Either recreate the unchanged data inside the transaction, or load the unchanged data before the transaction and delete it afterward. > I think it is a mistake to try to hide complexity from developers. They >> should be given the choice and should be able to understand the pros and >> contras of each approach and then make the decision. You're not responsible >> for other's mistake. >> > > You are entitled to your own opinion. However, in my opinion much of good > programming is hiding the underlying complexity from developers. > > > Yeah, but this rules applies to my situation as well. It would much less > complex for me to just call transaction.begin and transaction.rollback > instead of having to dig into Sequel's source code to call private methods > for doing what I want to. This is much more error prone and it makes it > much more difficult for other developers to understand it. Just like if > other developers are required to run "rails sc" instead of "rails c" if > they want to use a sandboxed version. > Well, like I mentioned above, there is a way to implement a correct sandbox in Sequel. > So, when you hide complexity by limiting the usage to the most-common form > you will be increasing complexity for other less common usage. > I'm OK with that, especially since the less common usage in this case is a usage case I don't want to encourage. > This is not a matter of being able or not. Other developers that looked at > my code should also be able to understand the code intention taking a > glance at it. Also, working with public API is much more future proof in > the sense that it is less likely that a Sequel upgrade would break our hack. > I don't think the Sequel code I gave you would be misunderstood in terms of intentions. It is true that a public API would be more future proof, but that would encourage people to rely on it, which I don't want people to do. > And JRuby was exactly what I had to resort at that time when I needed to > use my full CPU power for a processing intensive task that took about 2 > hours to complete. It would take about 12 hours to complete on MRI Ruby. If > you're curious for more details: > > > http://rosenfeld.herokuapp.com/en/articles/ruby-rails/2012-03-04-how-nokogiri-and-jruby-saved-my-week > > Even in single threaded code, JRuby often performs better. I'm not arguing that threads can't increase performance. But a multithreaded app is much more difficult to debug than a multiprocess app, in my experience. Jeremy -- You received this message because you are subscribed to the Google Groups "sequel-talk" group. To view this discussion on the web visit https://groups.google.com/d/msg/sequel-talk/-/7gymbl8lE_8J. To post to this group, send email to [email protected]. To unsubscribe from this group, send email to [email protected]. For more options, visit this group at http://groups.google.com/group/sequel-talk?hl=en.
