euston-daemons 1.0.5 → 1.2.1
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.
- data/Gemfile +4 -1
- data/Rakefile +2 -3
- data/euston-daemons.gemspec +50 -39
- data/lib/euston-daemons.rb +14 -1
- data/lib/euston-daemons/euston/daemon.rb +99 -0
- data/lib/euston-daemons/euston/daemon_component.rb +25 -0
- data/lib/euston-daemons/euston/daemon_component_host.rb +66 -0
- data/lib/euston-daemons/euston/daemon_environment.rb +59 -0
- data/lib/euston-daemons/euston/exceptions.rb +9 -0
- data/lib/euston-daemons/euston/stopwatch.rb +15 -0
- data/lib/euston-daemons/pipeline/config/environment.rb +78 -0
- data/lib/euston-daemons/pipeline/lib/command_logger/component.rb +54 -0
- data/lib/euston-daemons/pipeline/lib/command_logger/log.rb +31 -0
- data/lib/euston-daemons/pipeline/lib/command_processor/component.rb +50 -0
- data/lib/euston-daemons/pipeline/lib/command_processor/default_commands/retry_failed_message.rb +13 -0
- data/lib/euston-daemons/pipeline/lib/command_processor/default_handlers/retry_failed_message.rb +34 -0
- data/lib/euston-daemons/pipeline/lib/command_processor/failed_message.rb +36 -0
- data/lib/euston-daemons/pipeline/lib/daemon.rb +85 -0
- data/lib/euston-daemons/pipeline/lib/event_processor/component.rb +67 -0
- data/lib/euston-daemons/pipeline/lib/event_processor/default_handlers/message_failure.rb +30 -0
- data/lib/euston-daemons/pipeline/lib/event_store_dispatcher/component.rb +68 -0
- data/lib/euston-daemons/pipeline/lib/message_buffer/buffer.rb +85 -0
- data/lib/euston-daemons/pipeline/lib/message_buffer/component.rb +59 -0
- data/lib/euston-daemons/pipeline/lib/snapshotter/component.rb +48 -0
- data/lib/euston-daemons/pipeline/rake_task.rb +49 -0
- data/lib/euston-daemons/rake_task.rb +63 -66
- data/lib/euston-daemons/rake_tasks.rb +3 -5
- data/lib/euston-daemons/version.rb +1 -1
- data/spec/daemons/command_processor_spec.rb +48 -0
- data/spec/daemons/event_processor_spec.rb +55 -0
- data/spec/daemons/message_buffer_spec.rb +106 -0
- data/spec/daemons/snapshotter_spec.rb +96 -0
- data/spec/spec_helper.rb +91 -0
- data/spec/support/factories/commands.rb +16 -0
- data/spec/support/factories/commit.rb +7 -0
- data/spec/support/factories/event_message.rb +12 -0
- data/spec/support/factories/events.rb +8 -0
- data/spec/support/filters.rb +13 -0
- data/spec/support/sample_model/commands.rb +14 -0
- data/spec/support/sample_model/counter.rb +36 -0
- data/spec/support/sample_model/counter2.rb +46 -0
- data/spec/support/stub_retrying_subscription.rb +9 -0
- metadata +131 -67
- data/lib/euston-daemons/command_processor_daemon/config/environment.rb +0 -25
- data/lib/euston-daemons/command_processor_daemon/lib/components/command_handler_component.rb +0 -56
- data/lib/euston-daemons/command_processor_daemon/lib/daemon.rb +0 -43
- data/lib/euston-daemons/command_processor_daemon/lib/settings.rb +0 -22
- data/lib/euston-daemons/command_processor_daemon/rake_task.rb +0 -34
- data/lib/euston-daemons/event_processor_daemon/config/environment.rb +0 -25
- data/lib/euston-daemons/event_processor_daemon/lib/components/event_handler_component.rb +0 -58
- data/lib/euston-daemons/event_processor_daemon/lib/daemon.rb +0 -71
- data/lib/euston-daemons/event_processor_daemon/lib/settings.rb +0 -26
- data/lib/euston-daemons/event_processor_daemon/rake_task.rb +0 -37
- data/lib/euston-daemons/framework/basic_component.rb +0 -33
- data/lib/euston-daemons/framework/channel_thread.rb +0 -22
- data/lib/euston-daemons/framework/component_shutdown.rb +0 -22
- data/lib/euston-daemons/framework/daemon.rb +0 -27
- data/lib/euston-daemons/framework/handler_bindings_component.rb +0 -56
- data/lib/euston-daemons/framework/queue.rb +0 -71
- data/lib/euston-daemons/message_buffer_daemon/config/environment.rb +0 -28
- data/lib/euston-daemons/message_buffer_daemon/lib/components/buffer_component.rb +0 -73
- data/lib/euston-daemons/message_buffer_daemon/lib/components/event_store_component.rb +0 -52
- data/lib/euston-daemons/message_buffer_daemon/lib/daemon.rb +0 -48
- data/lib/euston-daemons/message_buffer_daemon/lib/message_logger.rb +0 -54
- data/lib/euston-daemons/message_buffer_daemon/lib/publisher.rb +0 -56
- data/lib/euston-daemons/message_buffer_daemon/lib/read_model/message_log.rb +0 -36
- data/lib/euston-daemons/message_buffer_daemon/lib/settings.rb +0 -14
- data/lib/euston-daemons/message_buffer_daemon/lib/subscriber.rb +0 -60
- data/lib/euston-daemons/message_buffer_daemon/rake_task.rb +0 -30
@@ -0,0 +1,30 @@
|
|
1
|
+
module Euston
|
2
|
+
module Daemons
|
3
|
+
module Pipeline
|
4
|
+
module EventProcessor
|
5
|
+
module DefaultHandlers
|
6
|
+
class MessageFailure
|
7
|
+
include Euston::EventHandler
|
8
|
+
|
9
|
+
subscribes :message_failed, 1 do |headers, event|
|
10
|
+
headers = event[:message][:headers].dup
|
11
|
+
failure = { :message_id => headers.delete(:id),
|
12
|
+
:type => headers.delete(:type),
|
13
|
+
:version => headers.delete(:version),
|
14
|
+
:message_timestamp => headers.delete(:timestamp),
|
15
|
+
:routing_key => event[:routing_key],
|
16
|
+
:body => event[:message][:body],
|
17
|
+
:headers => headers,
|
18
|
+
:error => event[:error],
|
19
|
+
:backtrace => event[:backtrace],
|
20
|
+
:failure_timestamp => Time.now.to_f }
|
21
|
+
|
22
|
+
failed_messages = CommandProcessor::FailedMessage.new DaemonEnvironment.event_store_mongodb
|
23
|
+
failed_messages.log_failure failure
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
module Euston
|
2
|
+
module Daemons
|
3
|
+
module Pipeline
|
4
|
+
module EventStoreDispatcher
|
5
|
+
class Component < DaemonComponent
|
6
|
+
extend RabbitMq::Exchanges
|
7
|
+
|
8
|
+
def initialize channel, id = 1, log = Euston::NullLogger.instance
|
9
|
+
@channel = channel
|
10
|
+
@channel.tx_select
|
11
|
+
@id = id
|
12
|
+
@log = log
|
13
|
+
@event_store = DaemonEnvironment.event_store
|
14
|
+
@stopwatch = Stopwatch.new.when(:finished => method(:log_elapsed_time))
|
15
|
+
@commands_exchange = self.class.get_exchange channel, :commands
|
16
|
+
@events_exchange = self.class.get_exchange channel, :events
|
17
|
+
@buffer = MessageBuffer::Buffer.new DaemonEnvironment.event_store_mongodb
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
def log_elapsed_time elapsed_time
|
23
|
+
@log.debug "Event store dispatcher #{@id} dispatched #{@commits_dispatched} commit(s) in #{elapsed_time} sec(s)" if @commits_dispatched > 0
|
24
|
+
end
|
25
|
+
|
26
|
+
def next_iteration
|
27
|
+
@commits_dispatched = 0
|
28
|
+
|
29
|
+
@stopwatch.time do
|
30
|
+
begin
|
31
|
+
@event_store.take_ownership_of_undispatched_commits @id
|
32
|
+
@commits = @event_store.get_undispatched_commits @id
|
33
|
+
|
34
|
+
begin
|
35
|
+
@commits.each do |commit|
|
36
|
+
commit.events.each do |event|
|
37
|
+
hash = event.to_hash
|
38
|
+
@events_exchange.publish ActiveSupport::JSON.encode(hash), self.class.default_publish_options.merge(:routing_key => "events.#{hash[:headers][:type]}")
|
39
|
+
end
|
40
|
+
|
41
|
+
commit.commands.each do |command|
|
42
|
+
hash = command.to_hash
|
43
|
+
|
44
|
+
if hash[:headers][:dispatch_at].nil?
|
45
|
+
@commands_exchange.publish ActiveSupport::JSON.encode(hash), self.class.default_publish_options.merge(:routing_key => "commands.#{hash[:headers][:type]}")
|
46
|
+
else
|
47
|
+
@buffer.enqueue :commands, hash, hash[:headers][:dispatch_at]
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
@channel.tx_commit
|
53
|
+
rescue StandardError => e
|
54
|
+
@channel.tx_rollback
|
55
|
+
raise e
|
56
|
+
end
|
57
|
+
|
58
|
+
@event_store.mark_commits_as_dispatched @commits
|
59
|
+
|
60
|
+
@commits_dispatched += @commits.size
|
61
|
+
end until stopped || @commits.empty?
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
@@ -0,0 +1,85 @@
|
|
1
|
+
module Euston
|
2
|
+
module Daemons
|
3
|
+
module Pipeline
|
4
|
+
module MessageBuffer
|
5
|
+
class Buffer
|
6
|
+
def initialize mongodb
|
7
|
+
name = 'message_buffer'
|
8
|
+
mongodb.create_collection name unless mongodb.collection_names.include? name
|
9
|
+
|
10
|
+
@name = name
|
11
|
+
@collection = mongodb.collection name
|
12
|
+
|
13
|
+
@collection.ensure_index [ ['message_id', Mongo::ASCENDING] ],
|
14
|
+
:unique => false,
|
15
|
+
:name => "#{name}_message_id_index"
|
16
|
+
|
17
|
+
@collection.ensure_index [ ['component_id', Mongo::ASCENDING],
|
18
|
+
['dispatch_at', Mongo::ASCENDING] ],
|
19
|
+
:unique => false,
|
20
|
+
:name => "#{name}_component_id_dispatch_at_index"
|
21
|
+
end
|
22
|
+
|
23
|
+
attr_reader :name
|
24
|
+
|
25
|
+
def delete_dispatched_messages component_id
|
26
|
+
@collection.remove({ 'component_id' => component_id }, :multi => true)
|
27
|
+
end
|
28
|
+
|
29
|
+
def enqueue exchange, message, dispatch_at = nil
|
30
|
+
messages = message
|
31
|
+
messages = [{ :hash => message, :dispatch_at => dispatch_at }] unless messages.is_a? Array
|
32
|
+
|
33
|
+
messages = messages.map do |m|
|
34
|
+
message_is_well_formed = m.is_a?(Hash) && m.has_key?(:hash) && m.has_key?(:dispatch_at)
|
35
|
+
m = { :hash => m, :dispatch_at => dispatch_at } unless message_is_well_formed
|
36
|
+
map_to_document exchange, m
|
37
|
+
end
|
38
|
+
|
39
|
+
@collection.insert(messages) unless messages.empty?
|
40
|
+
end
|
41
|
+
|
42
|
+
def find_dispatchable_messages component_id
|
43
|
+
query = { 'component_id' => component_id }
|
44
|
+
fields = ['exchange', 'type', 'json']
|
45
|
+
sort = [ 'dispatch_at', Mongo::ASCENDING ]
|
46
|
+
|
47
|
+
@collection.find query, :fields => fields, :sort => sort
|
48
|
+
end
|
49
|
+
|
50
|
+
def get_by_id id
|
51
|
+
@collection.find_one 'message_id' => id
|
52
|
+
end
|
53
|
+
|
54
|
+
def take_ownership_of_dispatchable_messages component_id
|
55
|
+
new_messages_eligible_for_dispatch = { 'component_id' => '',
|
56
|
+
'dispatch_at' => { '$lte' => Time.now.to_f } }
|
57
|
+
|
58
|
+
messages_stuck_in_other_components = { 'component_id' => { '$ne' => '' },
|
59
|
+
'dispatch_at' => { '$lte' => Time.now.to_f - 60 } }
|
60
|
+
|
61
|
+
query = { '$or' => [ new_messages_eligible_for_dispatch, messages_stuck_in_other_components ] }
|
62
|
+
doc = { '$set' => { 'component_id' => component_id } }
|
63
|
+
|
64
|
+
@collection.update query, doc, :multi => true
|
65
|
+
end
|
66
|
+
|
67
|
+
private
|
68
|
+
|
69
|
+
def map_to_document exchange, message
|
70
|
+
hash = message[:hash]
|
71
|
+
dispatch_at = (message[:dispatch_at] || Time.now.to_f).to_f
|
72
|
+
|
73
|
+
{ 'message_id' => hash[:headers][:id],
|
74
|
+
'exchange' => exchange,
|
75
|
+
'type' => hash[:headers][:type],
|
76
|
+
'component_id' => '',
|
77
|
+
'dispatch_at' => dispatch_at,
|
78
|
+
'dispatch_at_for_humans' => Time.at(dispatch_at),
|
79
|
+
'json' => ActiveSupport::JSON.encode(hash) }
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
module Euston
|
2
|
+
module Daemons
|
3
|
+
module Pipeline
|
4
|
+
module MessageBuffer
|
5
|
+
class Component < Euston::DaemonComponent
|
6
|
+
extend RabbitMq::Exchanges
|
7
|
+
|
8
|
+
def initialize channel, id = 1, logger = Euston::NullLogger.instance
|
9
|
+
@channel = channel
|
10
|
+
@channel.tx_select
|
11
|
+
@id = "message_buffer #{id}"
|
12
|
+
@log = logger
|
13
|
+
@buffer = Buffer.new DaemonEnvironment.event_store_mongodb
|
14
|
+
@stopwatch = Stopwatch.new.when(:finished => method(:log_elapsed_time))
|
15
|
+
end
|
16
|
+
|
17
|
+
private
|
18
|
+
|
19
|
+
def dispatch_due_messages
|
20
|
+
@dispatched_count = 0
|
21
|
+
|
22
|
+
@stopwatch.time do
|
23
|
+
@buffer.take_ownership_of_dispatchable_messages @id
|
24
|
+
|
25
|
+
begin
|
26
|
+
@buffer.find_dispatchable_messages(@id).each do |message|
|
27
|
+
exchange = self.class.get_exchange @channel, message['exchange']
|
28
|
+
exchange.publish message['json'], self.class.default_publish_options.merge(:routing_key => "#{exchange.name}.#{message['type']}")
|
29
|
+
@dispatched_count += 1
|
30
|
+
end
|
31
|
+
|
32
|
+
@channel.tx_commit
|
33
|
+
rescue StandardError => e
|
34
|
+
@channel.tx_rollback
|
35
|
+
raise e
|
36
|
+
end
|
37
|
+
|
38
|
+
@buffer.delete_dispatched_messages @id
|
39
|
+
end
|
40
|
+
|
41
|
+
@dispatched_count
|
42
|
+
end
|
43
|
+
|
44
|
+
def log_elapsed_time elapsed_time
|
45
|
+
@log.debug "Message buffer #{@id} dispatched #{@dispatched_count} message(s) in #{elapsed_time} sec(s)" if @dispatched_count > 0
|
46
|
+
end
|
47
|
+
|
48
|
+
def next_iteration
|
49
|
+
@messages_dispatched = 0
|
50
|
+
|
51
|
+
begin
|
52
|
+
@messages_dispatched = dispatch_due_messages
|
53
|
+
end until stopped || @messages_dispatched.zero?
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
module Euston
|
2
|
+
module Daemons
|
3
|
+
module Pipeline
|
4
|
+
module Snapshotter
|
5
|
+
class Component < Euston::DaemonComponent
|
6
|
+
def initialize event_store, threshold, id = 1, logger = Euston::NullLogger.instance
|
7
|
+
@event_store = event_store
|
8
|
+
@threshold = threshold
|
9
|
+
@id = id
|
10
|
+
@log = logger
|
11
|
+
end
|
12
|
+
|
13
|
+
private
|
14
|
+
|
15
|
+
def next_iteration
|
16
|
+
begin
|
17
|
+
stream_heads = @event_store.get_streams_to_snapshot @threshold
|
18
|
+
@log.debug "Found #{stream_heads.length} stream(s) eligible for snapshotting (threshold is #{@threshold})" if stream_heads.any?
|
19
|
+
|
20
|
+
stream_heads.each do |stream_head|
|
21
|
+
pair = @event_store.get_snapshot_stream_pair stream_head.stream_id
|
22
|
+
|
23
|
+
loader = RabbitMq::ConstantLoader.new
|
24
|
+
loader.when(:hit => ->(klass) { take_snapshot klass, pair },
|
25
|
+
:miss => ->(type) { Safely.report! "Snapshotter was unable to find a class: #{type}" })
|
26
|
+
|
27
|
+
loader.load pair.stream.committed_headers[:aggregate_type]
|
28
|
+
end
|
29
|
+
end until stopped || stream_heads.empty?
|
30
|
+
end
|
31
|
+
|
32
|
+
def take_snapshot klass, pair
|
33
|
+
instance = klass.hydrate pair.stream, pair.snapshot
|
34
|
+
snapshot = instance.take_snapshot
|
35
|
+
snapshot = EventStore::Snapshot.new pair.stream.stream_id,
|
36
|
+
pair.stream.stream_revision,
|
37
|
+
snapshot[:payload],
|
38
|
+
:version => snapshot[:version]
|
39
|
+
|
40
|
+
@log.debug "Writing snapshot: #{snapshot.inspect}"
|
41
|
+
|
42
|
+
@event_store.add_snapshot snapshot
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
module Euston
|
2
|
+
class PipelineRakeTask < Euston::Daemons::RakeTask
|
3
|
+
attr_accessor :amqp_config_path,
|
4
|
+
:command_handler_namespaces,
|
5
|
+
:daemon_config_path,
|
6
|
+
:event_handler_namespaces,
|
7
|
+
:mongo_config_path,
|
8
|
+
:user_defined_components
|
9
|
+
|
10
|
+
def initialize environment
|
11
|
+
super(environment, :pipeline_daemon)
|
12
|
+
end
|
13
|
+
|
14
|
+
def before_creating_task
|
15
|
+
@daemon_path = File.expand_path(File.dirname __FILE__) + File::SEPARATOR
|
16
|
+
@daemon_class = 'Euston::Daemons::Pipeline::Daemon'
|
17
|
+
end
|
18
|
+
|
19
|
+
def load_daemon_config_file
|
20
|
+
@data[:daemon_config] = ErbYaml.read @daemon_config_path, @data[:environment]
|
21
|
+
end
|
22
|
+
|
23
|
+
def initialize_settings
|
24
|
+
@logger.debug "AMQP config path: #{@amqp_config_path}"
|
25
|
+
@data[:amqp_config_path] = @amqp_config_path
|
26
|
+
|
27
|
+
@logger.debug "Command handler namespaces: #{@command_handler_namespaces}"
|
28
|
+
@data[:command_handler_namespaces] = @command_handler_namespaces
|
29
|
+
|
30
|
+
@logger.debug "Daemon config path: #{@daemon_config_path}"
|
31
|
+
|
32
|
+
@logger.debug "Event handler namespaces: #{@event_handler_namespaces}"
|
33
|
+
@data[:event_handler_namespaces] = @event_handler_namespaces
|
34
|
+
|
35
|
+
@logger.debug "Mongo config path: #{@mongo_config_path}"
|
36
|
+
@data[:mongo_config_path] = @mongo_config_path
|
37
|
+
|
38
|
+
@logger.debug "User-defined components: #{@user_defined_components.count}"
|
39
|
+
@data[:user_defined_components] = @user_defined_components.to_a.flatten
|
40
|
+
end
|
41
|
+
|
42
|
+
def load_environment
|
43
|
+
@logger.debug "Loading environment"
|
44
|
+
require 'euston-daemons/pipeline/config/environment'
|
45
|
+
|
46
|
+
Euston::Daemons::Pipeline::DaemonEnvironment.new(@data).setup
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -15,11 +15,8 @@ module Euston
|
|
15
15
|
# Daemon class. Must be supplied as a string.
|
16
16
|
attr_accessor :daemon_class
|
17
17
|
|
18
|
-
#
|
19
|
-
|
20
|
-
# default:
|
21
|
-
# /var/log/euston.log
|
22
|
-
attr_accessor :log_path
|
18
|
+
# Callable. Receives the daemon environment object to allow the user to perform other related config operations.
|
19
|
+
attr_accessor :post_setup_callback
|
23
20
|
|
24
21
|
# Use verbose output. If this is set to true, the task will print the
|
25
22
|
# executed command to stdout.
|
@@ -28,65 +25,51 @@ module Euston
|
|
28
25
|
# true
|
29
26
|
attr_accessor :verbose
|
30
27
|
|
31
|
-
def initialize
|
32
|
-
@name =
|
33
|
-
@log_path = '/var/log/euston.log'
|
28
|
+
def initialize environment, name = :euston_daemon
|
29
|
+
@name = name
|
34
30
|
@verbose = true
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
@pid_path = pid_path_for_env + "#{@name}.pid"
|
31
|
+
@environment = validate_environment environment
|
32
|
+
@data = { :environment => @environment }
|
39
33
|
|
40
34
|
yield self if block_given?
|
41
35
|
send :before_creating_task if respond_to? :before_creating_task
|
42
36
|
|
43
37
|
desc("Run a Euston daemon") unless ::Rake.application.last_comment
|
44
|
-
|
45
38
|
task name do
|
46
39
|
RakeFileUtils.send(:verbose, verbose) do
|
40
|
+
load_daemon_config_file
|
47
41
|
initialize_logger
|
42
|
+
initialize_settings
|
43
|
+
write_pid_file
|
48
44
|
log_startup
|
49
|
-
|
50
|
-
|
51
|
-
load_environment
|
45
|
+
env = load_environment
|
46
|
+
post_setup_callback.call env unless post_setup_callback.nil?
|
52
47
|
launch_and_wait_for_exit
|
53
48
|
log_shutdown
|
49
|
+
remove_pid_file
|
54
50
|
end
|
55
51
|
end
|
56
52
|
end
|
57
53
|
|
58
54
|
private
|
59
55
|
|
60
|
-
def
|
61
|
-
|
62
|
-
|
63
|
-
environment = :development unless environments.include? environment
|
64
|
-
environment
|
65
|
-
end
|
56
|
+
def initialize_logger
|
57
|
+
config = @data[:daemon_config]
|
58
|
+
log_path = config[:log_path]
|
66
59
|
|
67
|
-
|
68
|
-
case get_environment
|
69
|
-
when :development, :test
|
70
|
-
'~/var/run/euston/'
|
71
|
-
else
|
72
|
-
'/var/run/euston/'
|
73
|
-
end
|
74
|
-
end
|
60
|
+
raise "Required log path does not exist: #{log_path}" unless Dir.exist? log_path
|
75
61
|
|
76
|
-
|
77
|
-
Object.const_set :EUSTON_LOG, Logger.new(@log_path.gsub(/\.log$/, ".#{EUSTON_ENV}.log"))
|
78
|
-
end
|
62
|
+
@data[:logger] = @logger = Logger.new(File.join log_path, "#{@name}.#{@environment}.log")
|
79
63
|
|
80
|
-
|
81
|
-
|
64
|
+
begin
|
65
|
+
@logger.level = Logger.const_get config[:log_level].upcase.to_sym
|
66
|
+
rescue
|
67
|
+
@logger.level = Logger::DEBUG
|
68
|
+
end
|
82
69
|
end
|
83
70
|
|
84
|
-
def
|
85
|
-
|
86
|
-
Java::JavaIo::File.new("/proc/self").canonical_file.name
|
87
|
-
else
|
88
|
-
File.readlink("/proc/self")
|
89
|
-
end
|
71
|
+
def initialize_settings
|
72
|
+
# virtual
|
90
73
|
end
|
91
74
|
|
92
75
|
def launch_and_wait_for_exit
|
@@ -97,26 +80,15 @@ module Euston
|
|
97
80
|
ns = ns.const_get c.to_sym
|
98
81
|
end
|
99
82
|
|
100
|
-
|
101
|
-
create_pid_file
|
102
|
-
trap_exit_signals daemon
|
103
|
-
daemon.run
|
104
|
-
remove_pid_file
|
83
|
+
ns.new(@data).run
|
105
84
|
end
|
106
85
|
|
107
|
-
def
|
108
|
-
|
109
|
-
require_rel 'framework'
|
110
|
-
end
|
111
|
-
|
112
|
-
def create_pid_file
|
113
|
-
File.open( @pid_path, 'w' ) { |f|
|
114
|
-
f.puts rake_pid
|
115
|
-
}
|
86
|
+
def load_daemon_config_file
|
87
|
+
# virtual
|
116
88
|
end
|
117
89
|
|
118
|
-
def
|
119
|
-
|
90
|
+
def load_environment
|
91
|
+
# virtual
|
120
92
|
end
|
121
93
|
|
122
94
|
def log_shutdown
|
@@ -130,17 +102,42 @@ module Euston
|
|
130
102
|
def print_log_banner banner
|
131
103
|
border = '-' * banner.length
|
132
104
|
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
105
|
+
@logger.info ''
|
106
|
+
@logger.info border
|
107
|
+
@logger.info banner
|
108
|
+
@logger.info border
|
109
|
+
@logger.info ''
|
138
110
|
end
|
139
111
|
|
140
|
-
def
|
141
|
-
|
142
|
-
|
143
|
-
|
112
|
+
def remove_pid_file
|
113
|
+
@logger.debug "Deleting pid file at #{@pid_file}"
|
114
|
+
|
115
|
+
File.delete @pid_file rescue Errno::ENOENT
|
116
|
+
end
|
117
|
+
|
118
|
+
def validate_environment environment
|
119
|
+
environment = environment.to_s.downcase.to_sym
|
120
|
+
environments = [:development, :test, :staging, :production]
|
121
|
+
environment = :development unless environments.include? environment
|
122
|
+
environment
|
123
|
+
end
|
124
|
+
|
125
|
+
def write_pid_file
|
126
|
+
pid_path = @data[:daemon_config][:pid_path]
|
127
|
+
|
128
|
+
raise "Required pid path does not exist: #{pid_path}" unless Dir.exist? pid_path
|
129
|
+
|
130
|
+
@pid_file = File.join pid_path, "#{@name}.#{@environment}.pid"
|
131
|
+
|
132
|
+
if defined? Java
|
133
|
+
@pid = java.lang.management.ManagementFactory.getRuntimeMXBean().getName().split('@').first
|
134
|
+
else
|
135
|
+
@pid = File.readlink("/proc/self")
|
136
|
+
end
|
137
|
+
|
138
|
+
@logger.error "Writing pid #{@pid} to #{@pid_file}"
|
139
|
+
|
140
|
+
File.open(@pid_file, 'w') { |f| f.puts @pid }
|
144
141
|
end
|
145
142
|
end
|
146
143
|
end
|