easy_job 1.0.0.alpha → 1.0.0.beta

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: d4aebfe194102056b9da3a53a88cbb9cc29edf14
4
- data.tar.gz: 6fd93ce6449daab58c9f011281d756bfac6ebd12
3
+ metadata.gz: 06d362b4970f9a75202dfaac478eed36b453edad
4
+ data.tar.gz: 40a4a9a711c617f7b76476098e3611aab9b82ec9
5
5
  SHA512:
6
- metadata.gz: 4f7e11f580c8cf8ead56db8a0b25327aa4847ea3cb6234c1a9463685753f5867f761ea1f7bca450dfba2bb52b604ef4b395e209dc334990caa6c8c5fe92503ea
7
- data.tar.gz: a246b7327c7daf91e6a868b82df10c1da2ce185b4b20dfbd599b98b8f5cef1c626c90ddb615614fbfd5459d5f13491b4708dae3dac42b1c68edde17b8053ea24
6
+ metadata.gz: 0a1a9111d2ebae0034052e5b2a3dbf7ec79b12df9017296c04ddaaca502b4a6ef1afc48ac5d5c98e78edb1d7b2d630c31bb04d46a84920b765256b06f887174d
7
+ data.tar.gz: 790f2b27b1053aa0a1458363973d43675241c5c08fb5bde1b92c41f6d9c51097b93526adabfe3c2cd8e5cc6300e47c0001a9f0e6ca3d3ed4b566c1690017e29a
data/.gitignore CHANGED
@@ -7,3 +7,5 @@
7
7
  /pkg/
8
8
  /spec/reports/
9
9
  /tmp/
10
+ /.redmine/
11
+ /redmine.tar.gz
data/Gemfile CHANGED
@@ -2,3 +2,6 @@ source 'https://rubygems.org'
2
2
 
3
3
  # Specify your gem's dependencies in easy_job.gemspec
4
4
  gemspec
5
+
6
+ gem 'pry'
7
+ gem 'rspec-rails'
data/README.md CHANGED
@@ -1,8 +1,6 @@
1
1
  # EasyJob
2
2
 
3
- Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/easy_job`. To experiment with that code, run `bin/console` for an interactive prompt.
4
-
5
- TODO: Delete this and the text above, and describe your gem
3
+ Asynchronous job for Redmine, EasyRedmine and EasyProject.
6
4
 
7
5
  ## Installation
8
6
 
@@ -22,15 +20,62 @@ Or install it yourself as:
22
20
 
23
21
  ## Usage
24
22
 
25
- TODO: Write usage instructions here
23
+ ### Delay jobs
24
+
25
+ Every methods called after `.easy_delay` will be delayed and executed on other thread. This method could be used for any ruby Object.
26
+
27
+ ```ruby
28
+ # Reschedule first issue to today
29
+ Issue.first.easy_delay.reschedule_on(Date.today)
26
30
 
27
- ## Development
31
+ # Save ORM object with lot of callbacks
32
+ [Issue.new, Issue.new].map { |i| i.easy_delay.save }
33
+ ```
28
34
 
29
- After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
35
+ ### Mailer jobs
30
36
 
31
- To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
37
+ Deliver email later.
32
38
 
33
- ## Contributing
39
+ ```ruby
40
+ # Generating and sending will be done later
41
+ Mailer.issue_add(issue, ['test@example.net'], []).easy_deliver
42
+
43
+ # Email is generated now but send later
44
+ Mailer.issue_add(issue, ['test@example.net'], []).easy_safe_deliver
45
+ ```
34
46
 
35
- Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/easy_job.
47
+ ### Custom jobs
48
+
49
+ You can also create custom task with own exceptions capturing.
50
+
51
+ ```ruby
52
+ class PDFJob < EasyJob::RedmineTask
53
+
54
+ include IssuesHelper
55
+
56
+ def perform(issue_ids, project_id)
57
+ issues = Issue.where(id: issue_ids)
58
+ project = Project.find(project_id)
59
+ query = IssueQuery.new
60
+
61
+ result = issues_to_pdf(issues, project, query)
62
+
63
+ path = Rails.root.join('public', 'issues.pdf')
64
+ File.open(path, 'wb') {|f| f.write(result) }
65
+ end
66
+
67
+ end
68
+
69
+ PDFJob.perform_async(Issue.ids, Project.first.id)
70
+ ```
71
+
72
+ ## Ideas for next version
73
+
74
+ - Behaviour model.
75
+ - Repeat after failing.
76
+ - Dashboard.
77
+ - Queue defining.
78
+
79
+ ## Contributing
36
80
 
81
+ Bug reports and pull requests are welcome on GitHub at https://github.com/ondra-m/easy_job.
data/Rakefile CHANGED
@@ -1,6 +1,12 @@
1
- require "bundler/gem_tasks"
2
- require "rspec/core/rake_task"
1
+ require 'bundler/gem_tasks'
2
+ require 'rspec/core/rake_task'
3
3
 
4
4
  RSpec::Core::RakeTask.new(:spec)
5
5
 
6
- task :default => :spec
6
+ task default: :spec
7
+
8
+ namespace :test do
9
+ task :prepare do
10
+ Kernel.system('./test_prepare.sh')
11
+ end
12
+ end
data/easy_job.gemspec CHANGED
@@ -11,14 +11,12 @@ Gem::Specification.new do |spec|
11
11
  spec.authors = ['Ondřej Moravčík']
12
12
  spec.email = ['moravcik.ondrej@gmail.com']
13
13
 
14
- spec.summary = %q{Asynchronous job for easyproject}
14
+ spec.summary = %q{Asynchronous job for Redmine, EasyRedmine and EasyProject}
15
15
  spec.description = %q{}
16
16
  spec.homepage = 'https://github.com/ondra-m/easy_job'
17
17
  spec.license = 'MIT'
18
18
 
19
19
  spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
20
- # spec.bindir = 'exe'
21
- # spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
22
20
  spec.require_paths = ['lib']
23
21
 
24
22
  spec.required_ruby_version = '>= 2.1'
data/lib/easy_job.rb CHANGED
@@ -1,5 +1,77 @@
1
- require "easy_job/version"
1
+ require 'monitor'
2
+ require 'concurrent'
3
+ require 'securerandom'
4
+
5
+ require 'pry'
2
6
 
3
7
  module EasyJob
4
- # Your code goes here...
8
+ extend MonitorMixin
9
+
10
+ autoload :Task, 'easy_job/task'
11
+ autoload :RedmineTask, 'easy_job/redmine_task'
12
+ autoload :DelayTask, 'easy_job/delay_task'
13
+ autoload :DelayTaskProxy, 'easy_job/delay_task'
14
+ autoload :MailerTask, 'easy_job/mailer_task'
15
+ autoload :TaskWrapper, 'easy_job/task_wrapper'
16
+ autoload :Logger, 'easy_job/logger'
17
+ autoload :Queue, 'easy_job/queue'
18
+ autoload :Attribute, 'easy_job/attribute'
19
+ autoload :Logging, 'easy_job/logging'
20
+
21
+ def self.get_queue(name)
22
+ synchronize do
23
+ @@queues ||= Concurrent::Map.new
24
+ @@queues.fetch_or_store(name) { EasyJob::Queue.new(name) }
25
+ end
26
+ end
27
+
28
+ # Block `all_done?` method for `interval` seconds.
29
+ # Method `all_done?` is checking `scheduled_task_count`
30
+ # but `ScheduledTask` is added to executor queue after delay time.
31
+ def self.block_all_done_for(interval)
32
+ synchronize do
33
+ @@block_all_done_until ||= Time.now
34
+
35
+ new_time = Time.now + interval.to_f
36
+ if @@block_all_done_until < new_time
37
+ @@block_all_done_until = new_time
38
+ end
39
+ end
40
+ end
41
+
42
+ # One time, non-blocking.
43
+ def self.all_done?
44
+ synchronize do
45
+ return true if @@queues.nil?
46
+
47
+ @@block_all_done_until ||= Time.now
48
+ if @@block_all_done_until > Time.now
49
+ false
50
+ else
51
+ @@queues.values.map(&:all_done?).all?
52
+ end
53
+ end
54
+ end
55
+
56
+ # Blocking passive waiting.
57
+ def self.wait_for_all(wait_delay: 5)
58
+ loop {
59
+ if all_done?
60
+ return
61
+ else
62
+ sleep wait_delay
63
+ end
64
+ }
65
+ end
66
+
67
+ def self.logger
68
+ synchronize do
69
+ @@loger ||= Logger.new(Rails.root.join('log', 'easy_jobs.log'))
70
+ end
71
+ end
72
+
5
73
  end
74
+
75
+ require 'easy_job/version'
76
+ require 'easy_job/ext/object'
77
+ require 'easy_job/rails/message_delivery_patch'
@@ -0,0 +1,45 @@
1
+ module EasyJob
2
+ module Attribute
3
+
4
+ def self.included(base)
5
+ base.extend(Methods)
6
+ end
7
+
8
+ module Methods
9
+
10
+ def attribute(name, defaults=nil)
11
+ class_eval <<-METHODS
12
+ def self.#{name}=(value)
13
+ singleton_class.class_eval do
14
+ define_method(:#{name}) do |new_value=nil|
15
+ if new_value.nil?
16
+ value
17
+ else
18
+ self.#{name} = new_value
19
+ end
20
+ end
21
+ end
22
+
23
+ value
24
+ end
25
+
26
+ def self.#{name}?
27
+ !!#{name}
28
+ end
29
+
30
+ def #{name}
31
+ self.class.#{name}
32
+ end
33
+
34
+ def #{name}?
35
+ self.class.#{name}?
36
+ end
37
+ METHODS
38
+
39
+ self.send("#{name}=", defaults)
40
+ end
41
+
42
+ end
43
+
44
+ end
45
+ end
@@ -0,0 +1,109 @@
1
+ # Behavior model
2
+ #
3
+ # NOT used in current version
4
+ # Just and idea
5
+
6
+ ##
7
+ # EasyJob::Behavior
8
+ #
9
+ # Container for behavior definition
10
+ #
11
+ module EasyJob
12
+ class Behavior
13
+
14
+ @@behaviors = {}
15
+
16
+ def self.define(name, &block)
17
+ @@behaviors[name] = new(name, &block)
18
+ end
19
+
20
+ def self.get(name)
21
+ @@behaviors[name]
22
+ end
23
+
24
+ def initialize(name, &block)
25
+ @name = name
26
+ instance_eval(&block)
27
+ end
28
+
29
+ def on_create
30
+ if block_given?
31
+ @on_create = Proc.new
32
+ else
33
+ @on_create || proc{}
34
+ end
35
+ end
36
+
37
+ end
38
+ end
39
+
40
+ ##
41
+ # EasyJob::TaskWrapper
42
+ #
43
+ # Modified wrapper
44
+ #
45
+ module EasyJob
46
+ class TaskWrapper
47
+
48
+ def initialize(task_class, args)
49
+ @behaviors = Array(task_class.behaviors)
50
+ @behaviors.map!{|b| Behavior.get(b) }
51
+ @behaviors.compact!
52
+
53
+ @behaviors.each{|b| instance_eval(&b.on_initialize) }
54
+ end
55
+
56
+ def perform
57
+ end
58
+
59
+ end
60
+ end
61
+
62
+
63
+ ##
64
+ # Definition of behavior
65
+ #
66
+ EasyJob::Behavior.define 'Database' do
67
+
68
+ on_create do
69
+ @connection_attempt = 0
70
+ end
71
+
72
+ on_perform do |task|
73
+ begin
74
+ ActiveRecord::Base.connection_pool.with_connection { task.run }
75
+ rescue ActiveRecord::ConnectionTimeoutError
76
+ @connection_attempt += 1
77
+ if @connection_attempt > max_db_connection_attempts
78
+ log_error 'Max ConnectionTimeoutError'
79
+ return
80
+ else
81
+ log_warn "ConnectionTimeoutError attempt=#{@connection_attempt}"
82
+ retry
83
+ end
84
+ end
85
+ end
86
+
87
+ end
88
+
89
+ EasyJob::Behavior.define 'RedmineEnv' do
90
+
91
+ on_create do
92
+ @current_user = User.current
93
+ @current_locale = I18n.locale
94
+ end
95
+
96
+ on_create do |task|
97
+ begin
98
+ orig_user = User.current
99
+ orig_locale = I18n.locale
100
+ User.current = @current_user
101
+ I18n.locale = @current_locale
102
+ super
103
+ ensure
104
+ User.current = orig_user
105
+ I18n.locale = orig_locale
106
+ end
107
+ end
108
+
109
+ end
@@ -0,0 +1,48 @@
1
+ class EasyJob::DelayTaskProxy < BasicObject
2
+
3
+ def initialize(object)
4
+ @object = object
5
+ @chains = []
6
+ end
7
+
8
+ def __object
9
+ @object
10
+ end
11
+
12
+ def __chains
13
+ @chains
14
+ end
15
+
16
+ def easy_delay
17
+ self
18
+ end
19
+
20
+ def method_missing(name, *args, &block)
21
+ @chains << [name, args, block]
22
+ if @chains.size == 1
23
+ ::EasyJob::DelayTask.perform_in(1, self)
24
+ end
25
+ self
26
+ end
27
+
28
+ end
29
+
30
+ ##
31
+ # EasyJob::DelayTask
32
+ #
33
+ # Run chains of commands deleyed
34
+ #
35
+ # Issue.first.easy_delay.reschedule_on(Date.today)
36
+ #
37
+ class EasyJob::DelayTask < EasyJob::RedmineTask
38
+
39
+ def perform(proxy)
40
+ object = proxy.__object
41
+ chains = proxy.__chains
42
+
43
+ chains.each do |name, args, block|
44
+ object = object.send(name, *args, &block)
45
+ end
46
+ end
47
+
48
+ end
@@ -0,0 +1,23 @@
1
+ class Object
2
+
3
+ # Be carefull with nested calling. Parameters could be generated some times.
4
+ #
5
+ # # It's OK
6
+ # Issue.first.easy_delay.reschedule_on(Date.today)
7
+ #
8
+ # # This could be a problem
9
+ # def calc_date
10
+ # sleep 100
11
+ # Date.today
12
+ # end
13
+ #
14
+ # Issue.easy_delay.first.reschedule_on(calc_date)
15
+ #
16
+ # On second example only `first` method will be executed because Job does not know
17
+ # how many calling be triggered. Small workaround: method is delayed for 1s.
18
+ #
19
+ def easy_delay
20
+ EasyJob::DelayTaskProxy.new(self)
21
+ end
22
+
23
+ end
@@ -0,0 +1,13 @@
1
+ module EasyJob
2
+ class Logger < ::Logger
3
+
4
+ def initialize(*args)
5
+ super $stdout
6
+ self.formatter = proc do |severity, datetime, progname, msg|
7
+ time = datetime.strftime('%H:%M:%S')
8
+ "#{severity.first}, [#{time}] #{msg}\n"
9
+ end
10
+ end
11
+
12
+ end
13
+ end
@@ -0,0 +1,48 @@
1
+ module EasyJob
2
+ module Logging
3
+
4
+ def self.included(base)
5
+ base.include(InstanceMethods)
6
+ base.extend(ClassMethods)
7
+ end
8
+
9
+ module InstanceMethods
10
+
11
+ def log_info(message)
12
+ message = "#{self.class.name}:#{job_id} - #{message}"
13
+ EasyJob.logger.info(message)
14
+ end
15
+
16
+ def log_warn(message)
17
+ message = "#{self.class.name}:#{job_id} - #{message}"
18
+ EasyJob.logger.warn(message)
19
+ end
20
+
21
+ def log_error(message)
22
+ message = "#{self.class.name}:#{job_id} - #{message}"
23
+ EasyJob.logger.error(message)
24
+ end
25
+
26
+ end
27
+
28
+ module ClassMethods
29
+
30
+ def log_info(message)
31
+ message = "#{self.name} - #{message}"
32
+ EasyJob.logger.info(message)
33
+ end
34
+
35
+ def log_warn(message)
36
+ message = "#{self.name} - #{message}"
37
+ EasyJob.logger.warn(message)
38
+ end
39
+
40
+ def log_error(message)
41
+ message = "#{self.name} - #{message}"
42
+ EasyJob.logger.error(message)
43
+ end
44
+
45
+ end
46
+
47
+ end
48
+ end
@@ -0,0 +1,14 @@
1
+ class EasyJob::MailerTask < EasyJob::RedmineTask
2
+
3
+ def perform(message)
4
+ case message
5
+ when ActionMailer::MessageDelivery
6
+ # Generate mail and send it
7
+ message.deliver_now
8
+ when Mail::Message
9
+ # Already generated, just send it
10
+ message.deliver
11
+ end
12
+ end
13
+
14
+ end
@@ -0,0 +1,43 @@
1
+ module EasyJob
2
+ class Queue < Concurrent::Synchronization::LockableObject
3
+
4
+ attr_reader :pool
5
+
6
+ # == ThreadPoolExecutor options:
7
+ # idletime::
8
+ # The number of seconds that a thread may be idle before being reclaimed
9
+ #
10
+ # auto_terminate::
11
+ # When true (default) an at_exit handler will be registered which
12
+ # will stop the thread pool when the application exits
13
+ #
14
+ # max_queue::
15
+ # 0 is unlimited
16
+ #
17
+ DEFAULT_EXECUTOR_OPTIONS = {
18
+ min_threads: 3,
19
+ max_threads: 3,
20
+ idletime: 60,
21
+ max_queue: 0,
22
+ auto_terminate: false
23
+ }
24
+
25
+ def initialize(name)
26
+ super()
27
+ @name = name
28
+ @pool = Concurrent::ThreadPoolExecutor.new(DEFAULT_EXECUTOR_OPTIONS)
29
+ end
30
+
31
+ def post(*args, &block)
32
+ synchronize {
33
+ @pool.post(*args, &block)
34
+ }
35
+ end
36
+
37
+ # It will work only if perform method was wrapped by begin rescue end
38
+ def all_done?
39
+ pool.scheduled_task_count == pool.completed_task_count
40
+ end
41
+
42
+ end
43
+ end
@@ -0,0 +1,54 @@
1
+ module EasyJob
2
+ ##
3
+ # ActionMailer::MessageDelivery
4
+ #
5
+ # It's a delegator which is created on method_missing.
6
+ #
7
+ module MessageDeliveryPatch
8
+
9
+ def self.included(base)
10
+ if Rails.env.test?
11
+ base.send(:include, TestInstanceMethods)
12
+ else
13
+ base.send(:include, InstanceMethods)
14
+ end
15
+ end
16
+
17
+ module InstanceMethods
18
+
19
+ # Mail will be generated and sent later
20
+ #
21
+ # Mailer.issue_add(issue, [], []).easy_deliver
22
+ #
23
+ def easy_deliver
24
+ EasyJob::MailerTask.perform_async(self)
25
+ end
26
+
27
+ # Mail is generated now and sent later
28
+ #
29
+ # Mailer.issue_add(issue, [], []).easy_deliver
30
+ #
31
+ def easy_safe_deliver
32
+ EasyJob::MailerTask.perform_async(message)
33
+ end
34
+
35
+ end
36
+
37
+ module TestInstanceMethods
38
+
39
+ def easy_deliver
40
+ deliver
41
+ end
42
+
43
+ def easy_safe_deliver
44
+ deliver
45
+ end
46
+
47
+ end
48
+
49
+ end
50
+ end
51
+
52
+ if defined?(ActionMailer)
53
+ ActionMailer::MessageDelivery.include(EasyJob::MessageDeliveryPatch)
54
+ end
@@ -0,0 +1,7 @@
1
+ module EasyJob
2
+ class RedmineTask < Task
3
+
4
+
5
+ end
6
+ end
7
+
@@ -0,0 +1,38 @@
1
+ module EasyJob
2
+ class Task
3
+ include Attribute
4
+ include Logging
5
+
6
+ attribute :queue_name, 'default'
7
+
8
+ attr_accessor :job_id
9
+
10
+ def self.perform_async(*args)
11
+ wrapper = TaskWrapper.new(self, args)
12
+ queue = EasyJob.get_queue(queue_name)
13
+ queue.post(wrapper, &:perform)
14
+ wrapper
15
+ end
16
+
17
+ def self.perform_in(interval, *args)
18
+ wrapper = TaskWrapper.new(self, args)
19
+ queue = EasyJob.get_queue(queue_name)
20
+ concurrent_job = Concurrent::ScheduledTask.execute(interval.to_f, args: wrapper, executor: queue.pool, &:perform)
21
+ EasyJob.block_all_done_for(interval)
22
+ wrapper
23
+ end
24
+
25
+ def perform(*)
26
+ raise NotImplementedError
27
+ end
28
+
29
+ def handle_error(ex)
30
+ log_error ex.message
31
+ ex.backtrace.each do |line|
32
+ log_error line
33
+ end
34
+ end
35
+
36
+ end
37
+ end
38
+
@@ -0,0 +1,86 @@
1
+ module EasyJob
2
+ class TaskWrapper
3
+ include Logging
4
+
5
+ STATE_PENDING = 0
6
+ STATE_RUNNING = 1
7
+ STATE_FINISHED = 2
8
+
9
+ def initialize(task_class, args)
10
+ @task_class = task_class
11
+ @args = args
12
+ @state = STATE_PENDING
13
+
14
+ @connection_attempt = 0
15
+ @current_user = User.current
16
+ @current_locale = I18n.locale
17
+ end
18
+
19
+ def job_id
20
+ @job && @job.job_id
21
+ end
22
+
23
+ def pending?
24
+ @state == STATE_PENDING
25
+ end
26
+
27
+ def running?
28
+ @state == STATE_RUNNING
29
+ end
30
+
31
+ def finished?
32
+ @state == STATE_FINISHED
33
+ end
34
+
35
+ def perform
36
+ @job = @task_class.new
37
+ @job.job_id = SecureRandom.uuid
38
+
39
+ ensure_connection {
40
+ ensure_redmine_env {
41
+ begin
42
+ @state = STATE_RUNNING
43
+ @job.perform(*@args)
44
+ rescue => ex
45
+ @job.handle_error(ex)
46
+ ensure
47
+ @state = STATE_FINISHED
48
+ log_info 'Job ended'
49
+ end
50
+ }
51
+ }
52
+ rescue => e
53
+ # Perform method must end successfully.
54
+ # Otherwise `all_done?` end on deadlock.
55
+ end
56
+
57
+ def ensure_connection
58
+ ActiveRecord::Base.connection_pool.with_connection { yield }
59
+ rescue ActiveRecord::ConnectionTimeoutError
60
+ @connection_attempt += 1
61
+ if @connection_attempt > max_db_connection_attempts
62
+ log_error 'Max ConnectionTimeoutError'
63
+ return
64
+ else
65
+ log_warn "ConnectionTimeoutError attempt=#{@connection_attempt}"
66
+ retry
67
+ end
68
+ end
69
+
70
+ def ensure_redmine_env
71
+ orig_user = User.current
72
+ orig_locale = I18n.locale
73
+ User.current = @current_user
74
+ I18n.locale = @current_locale
75
+ yield
76
+ ensure
77
+ User.current = orig_user
78
+ I18n.locale = orig_locale
79
+ end
80
+
81
+ def inspect
82
+ %{#<EasyJob::TaskWrapper(#{@task_class}) id="#{job_id}">}
83
+ end
84
+
85
+ end
86
+ end
@@ -1,3 +1,3 @@
1
- class EasyJob
2
- VERSION = '1.0.0.alpha'
1
+ module EasyJob
2
+ VERSION = '1.0.0.beta'
3
3
  end
data/test_prepare.sh ADDED
@@ -0,0 +1,42 @@
1
+ #!/usr/bin/env bash
2
+
3
+ # -v print lines as they are read
4
+ # -x print lines as they are executed
5
+ # -e abort script at first error
6
+ set -e
7
+
8
+ if [[ ! -d ".redmine" ]]; then
9
+ mkdir .redmine
10
+ pushd .redmine
11
+ # Download and extract redmine
12
+ wget "http://www.redmine.org/releases/redmine-3.3.0.tar.gz" -O redmine.tar.gz
13
+ tar xzf redmine.tar.gz --strip 1
14
+
15
+ # Init gems
16
+ echo "
17
+ gem 'pry'
18
+ gem 'pry-rails'
19
+ gem 'puma'
20
+ gem 'easy_job', path: '../'
21
+ " > Gemfile.local
22
+
23
+ # Init database
24
+ ruby -ryaml -e "
25
+ config = {
26
+ 'adapter' => 'postgresql',
27
+ 'database' => 'easy_job_redmine',
28
+ 'host' => '127.0.0.1',
29
+ 'encoding' => 'utf8'
30
+ }
31
+ config = { 'development' => config, 'production' => config }.to_yaml
32
+ File.write('config/database.yml', config)
33
+ "
34
+
35
+ # Install
36
+ bundle --local
37
+ bundle exec rake db:create RAILS_ENV=production
38
+ bundle exec rake db:migrate RAILS_ENV=production
39
+ bundle exec rake generate_secret_token RAILS_ENV=production
40
+ bundle exec rake redmine:load_default_data REDMINE_LANG=en RAILS_ENV=production
41
+ popd
42
+ fi
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: easy_job
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0.alpha
4
+ version: 1.0.0.beta
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ondřej Moravčík
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-08-18 00:00:00.000000000 Z
11
+ date: 2016-09-30 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: concurrent-ruby
@@ -81,8 +81,20 @@ files:
81
81
  - Rakefile
82
82
  - easy_job.gemspec
83
83
  - lib/easy_job.rb
84
- - lib/easy_job/easy_job.rb
84
+ - lib/easy_job/attribute.rb
85
+ - lib/easy_job/behavior.rb
86
+ - lib/easy_job/delay_task.rb
87
+ - lib/easy_job/ext/object.rb
88
+ - lib/easy_job/logger.rb
89
+ - lib/easy_job/logging.rb
90
+ - lib/easy_job/mailer_task.rb
91
+ - lib/easy_job/queue.rb
92
+ - lib/easy_job/rails/message_delivery_patch.rb
93
+ - lib/easy_job/redmine_task.rb
94
+ - lib/easy_job/task.rb
95
+ - lib/easy_job/task_wrapper.rb
85
96
  - lib/easy_job/version.rb
97
+ - test_prepare.sh
86
98
  homepage: https://github.com/ondra-m/easy_job
87
99
  licenses:
88
100
  - MIT
@@ -106,5 +118,5 @@ rubyforge_project:
106
118
  rubygems_version: 2.5.1
107
119
  signing_key:
108
120
  specification_version: 4
109
- summary: Asynchronous job for easyproject
121
+ summary: Asynchronous job for Redmine, EasyRedmine and EasyProject
110
122
  test_files: []
@@ -1,3 +0,0 @@
1
- class EasyJob
2
-
3
- end