Feature #12097

Multi Thread Support

Added by Daniel Morgan almost 6 years ago. Updated 9 months ago.

Status:ClosedStart date:
Priority:NormalDue date:
Assignee:-% Done:

0%

Category:Rails support
Target version:3.0.0
Resolution:Fixed

Description

Are there any plans for making Redmine thread safe in the future?
This is one of very important advantages of using Redmine with JRuby.

I have managed to enable config.threadsafe! with Redmine 1.4.x and gain thread safety to some extent.
However, I am really struggling to get it working with 2.x. (Mainly related to dependency loading disabled)

Will the Developers please consider thread safety in a future release.
My understanding is that config.threadsafe! will be a default in Rails 4.

For starters, the following fix was required in "app/models/user.rb" with 1.4.x:

  def self.current=(user)
    # @current_user = user
    Thread.current[:current_user] = user
  end

  def self.current
    # @current_user ||= User.anonymous
    Thread.current[:current_user] ||= User.anonymous
  end

This was to prevent current_user set by a user performing a bulk edit being overridden by a different user performing a concurrent request.

config.threadsafe-r12424.diff Magnifier (1.38 KB) Toshi MARUYAMA, 2013-12-21 03:43

unit-test-r12424.log.txt Magnifier (7.66 KB) Toshi MARUYAMA, 2013-12-21 03:43

rails4threadsafepatch.diff Magnifier - Numa's diff for making Redmine work on Rails 4 Threadsafe modified, untested (2.98 KB) Christopher Mann, 2014-05-02 10:04

threadsafe_redmine_patch.diff Magnifier - The correct diff file for Numa's implementation of Threadsafe. (27.3 KB) Christopher Mann, 2014-05-02 13:03

thread-r13171.diff Magnifier (2.77 KB) Toshi MARUYAMA, 2014-05-26 06:23

thread-r13171-1.diff Magnifier (2.29 KB) Toshi MARUYAMA, 2014-05-26 08:13


Related issues

Related to Redmine - Feature #14534: Upgrade to Rails 4.2 Closed

Associated revisions

Revision 10909
Added by Jean-Philippe Lang over 5 years ago

Explicitly load dependencies for when running with config.threadsafe! (#12097).

Revision 10910
Added by Jean-Philippe Lang over 5 years ago

Make the tests pass when config.threadsafe! is enabled (#12097).

Revision 10911
Added by Jean-Philippe Lang over 5 years ago

Makes User.current thread safe (#12097).

Revision 10912
Added by Jean-Philippe Lang over 5 years ago

Fixed dependency loading for when running in dev mode (#12097).

Revision 10915
Added by Jean-Philippe Lang over 5 years ago

Load RMagick before the gantt helper (#12097).

Revision 10944
Added by Jean-Philippe Lang over 5 years ago

Prevents redmine/scm/base from being reloaded in dev mode (#12097).

Revision 12427
Added by Toshi MARUYAMA over 4 years ago

make IssuesHelperTest passes when config.threadsafe! is enabled (#12097)

Revision 12428
Added by Toshi MARUYAMA over 4 years ago

make WatchersHelperTest passes when config.threadsafe! is enabled (#12097)

Revision 13170
Added by Toshi MARUYAMA about 4 years ago

fix ProjectsHelperTest fails when config.threadsafe! is enabled (#12097)

History

#1 Updated by Jean-Philippe Lang over 5 years ago

  • Target version set to Candidate for next minor release

The dependency loading issue should be fixed by r10909. After that, Redmine starts/runs fine with config.threadsafe!.

#2 Updated by Daniel Felix over 5 years ago

@Daniel Morgan
Can you confirm, that this revisions fix your problem?

Jean-Philippe Lang wrote:

The dependency loading issue should be fixed by r10909. After that, Redmine starts/runs fine with config.threadsafe!.

#3 Updated by Daniel Morgan over 5 years ago

@Jean-Philippe Lang

Thank you very much for considering some work on this.

@Daniel Felix

A quick check hasn't resulted in any issues.
However, I do get migration errors with config.threadsafe! set.

Error details using both r10909 and r10944:

E:\torquebox\redmine-trunk>jruby -S rake --trace db:migrate RAILS_ENV=production

** Invoke db:migrate (first_time)
** Invoke environment (first_time)
** Execute environment
** Invoke db:load_config (first_time)
** Execute db:load_config
** Execute db:migrate
==  Setup: migrating ==========================================================

:
:
:

==  AddIssueStatusPosition: migrating =========================================
-- add_column(:issue_statuses, :position, :integer, {:default=>1})
   -> 0.0510s
   -> 0 rows
rake aborted!
An error has occurred, all later migrations canceled:

uninitialized constant AddIssueStatusPosition::IssueStatus
org/jruby/RubyModule.java:2677:in `const_missing'
org/jruby/RubyMethod.java:134:in `call'
E:/torquebox/redmine-trunk/db/migrate/019_add_issue_status_position.rb:4:in `up'
E:/torquebox/jruby/lib/ruby/gems/shared/gems/activerecord-3.2.9/lib/active_record/migration.rb:370:in `up'
org/jruby/RubyKernel.java:2069:in `send'
E:/torquebox/jruby/lib/ruby/gems/shared/gems/activerecord-3.2.9/lib/active_record/migration.rb:410:in `migrate'
E:/torquebox/jruby/lib/ruby/1.8/benchmark.rb:293:in `measure'
E:/torquebox/jruby/lib/ruby/gems/shared/gems/activerecord-3.2.9/lib/active_record/migration.rb:410:in `migrate'
E:/torquebox/jruby/lib/ruby/gems/shared/gems/activerecord-3.2.9/lib/active_record/connection_adapters/abstract/connection_pool.rb:129:in `with_connection'
E:/torquebox/jruby/lib/ruby/gems/shared/gems/activerecord-3.2.9/lib/active_record/migration.rb:389:in `migrate'
org/jruby/RubyKernel.java:2073:in `send'
E:0:in `migrate'
E:/torquebox/jruby/lib/ruby/gems/shared/gems/activerecord-3.2.9/lib/active_record/migration.rb:720:in `migrate'
org/jruby/RubyProc.java:261:in `call'
org/jruby/RubyProc.java:209:in `call'
E:/torquebox/jruby/lib/ruby/gems/shared/gems/activerecord-3.2.9/lib/active_record/migration.rb:777:in `ddl_transaction'
E:/torquebox/jruby/lib/ruby/gems/shared/gems/activerecord-3.2.9/lib/active_record/migration.rb:719:in `migrate'
org/jruby/RubyArray.java:1613:in `each'
E:/torquebox/jruby/lib/ruby/gems/shared/gems/activerecord-3.2.9/lib/active_record/migration.rb:700:in `migrate'
E:/torquebox/jruby/lib/ruby/gems/shared/gems/activerecord-3.2.9/lib/active_record/migration.rb:570:in `up'
E:/torquebox/jruby/lib/ruby/gems/shared/gems/activerecord-3.2.9/lib/active_record/migration.rb:551:in `migrate'
E:/torquebox/jruby/lib/ruby/gems/shared/gems/activerecord-3.2.9/lib/active_record/railties/databases.rake:179:in `(root)'
org/jruby/RubyProc.java:261:in `call'
org/jruby/RubyProc.java:209:in `call'
E:/torquebox/jruby/lib/ruby/gems/shared/gems/rake-10.0.3/lib/rake/task.rb:228:in `execute'
org/jruby/RubyArray.java:1613:in `each'
E:/torquebox/jruby/lib/ruby/gems/shared/gems/rake-10.0.3/lib/rake/task.rb:223:in `execute'
E:/torquebox/jruby/lib/ruby/gems/shared/gems/rake-10.0.3/lib/rake/task.rb:166:in `invoke_with_call_chain'
E:/torquebox/jruby/lib/ruby/1.8/monitor.rb:191:in `mon_synchronize'
E:/torquebox/jruby/lib/ruby/gems/shared/gems/rake-10.0.3/lib/rake/task.rb:159:in `invoke_with_call_chain'
E:/torquebox/jruby/lib/ruby/gems/shared/gems/rake-10.0.3/lib/rake/task.rb:152:in `invoke'
E:/torquebox/jruby/lib/ruby/gems/shared/gems/rake-10.0.3/lib/rake/application.rb
:143:in `invoke_task'
E:/torquebox/jruby/lib/ruby/gems/shared/gems/rake-10.0.3/lib/rake/application.rb
:101:in `top_level'
org/jruby/RubyArray.java:1613:in `each'
E:/torquebox/jruby/lib/ruby/gems/shared/gems/rake-10.0.3/lib/rake/application.rb
:101:in `top_level'
E:/torquebox/jruby/lib/ruby/gems/shared/gems/rake-10.0.3/lib/rake/application.rb
:110:in `run_with_threads'
E:/torquebox/jruby/lib/ruby/gems/shared/gems/rake-10.0.3/lib/rake/application.rb
:95:in `top_level'
E:/torquebox/jruby/lib/ruby/gems/shared/gems/rake-10.0.3/lib/rake/application.rb
:73:in `run'
E:/torquebox/jruby/lib/ruby/gems/shared/gems/rake-10.0.3/lib/rake/application.rb
:160:in `standard_exception_handling'
E:/torquebox/jruby/lib/ruby/gems/shared/gems/rake-10.0.3/lib/rake/application.rb
:70:in `run'
E:/torquebox/jruby/lib/ruby/gems/shared/gems/rake-10.0.3/bin/rake:33:in `(root)'

org/jruby/RubyKernel.java:1041:in `load'
E:/torquebox/jruby/bin/rake:23:in `(root)'
Tasks: TOP => db:migrate

E:\torquebox\redmine-trunk>

#5 Updated by Numa Schmeder almost 5 years ago

I have a working threadsafe version running on Jruby since a few months. It's working like a charm and is very fast.
I had to modify many, many files to make it work. I still have the sources and the modified the files. If anyone is ready to build a patch, I can post the modified files (I don't have any time right now to do it).
One would have to compare each file with the current trunk version and create patches from it or at least a change log.

Regards,

#6 Updated by Daniel Morgan almost 5 years ago

@Numa Schmeder

Could you possibly upload your modified version of redmine onto GitHub or somewhere similar?
(with information of which revision you based your modifications on)

#7 Updated by Toshi MARUYAMA over 4 years ago

#8 Updated by Toshi MARUYAMA over 4 years ago

These are patch and unit test log.
Functional tests have many errors.

#9 Updated by Christopher Mann about 4 years ago

Please disregard previous file.

The current attached file has changes to about 20 files. This is Numa's correct Diff.

Here is Numa Schmeder's modification to make Redmine work in threadsafe mode in Rails 4 (see attached file).

It mainly has to do with added require statements.

#10 Updated by Christopher Mann about 4 years ago

Please disregard previous patch file and consider this one for Rails 4 threadsafe implementation.

#11 Updated by Toshi MARUYAMA about 4 years ago

This is patch for r13171.

Tests on Travis.
https://travis-ci.org/marutosi/redmine/builds/25998010

Only one test fails.

  1) Failure:
test_macro_include(Redmine::WikiFormatting::MacrosTest)
    [test/test_helper.rb:185:in `assert_include'
     test/unit/lib/redmine/wiki_formatting/macros_test.rb:199:in `test_macro_include']:
"This is a link to a ticket" not found in "<p><div class="flash error">Error executing the <strong>include</strong> macro (Circular inclusion detected)</div></p>".
<false> is not true.

Christopher Mann wrote:

Please disregard previous patch file and consider this one for Rails 4 threadsafe implementation.

Sorry, I cannot understand your patch means.
Rails4 porting issue is #14534.

#12 Updated by Toshi MARUYAMA about 4 years ago

Sorry, note-11 patch has duplicate code.
This is new patch.

Test results are same with note-11.
https://travis-ci.org/marutosi/redmine/builds/26022443

#13 Updated by Toshi MARUYAMA almost 4 years ago

#14 Updated by Toshi MARUYAMA almost 4 years ago

#15 Updated by Toshi MARUYAMA almost 4 years ago

  • Target version changed from Candidate for next minor release to 3.0.0

#16 Updated by Jean-Philippe Lang over 3 years ago

  • Assignee set to Toshi MARUYAMA

Can we close this?

#17 Updated by Toshi MARUYAMA over 3 years ago

  • Status changed from New to Closed
  • Assignee deleted (Toshi MARUYAMA)

http://edgeguides.rubyonrails.org/4_0_release_notes.html#general

Thread safe by default - Rails can run in threaded app servers without additional configuration

#18 Updated by Toshi MARUYAMA over 3 years ago

  • Resolution set to Fixed

I forgot to change resolution.

Also available in: Atom PDF