pione 0.1.2 → 0.1.3
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +2 -1
- data/History.txt +11 -0
- data/LICENSE.txt +1 -1
- data/README.md +1 -1
- data/bin/pione-log +5 -0
- data/example/CountChar/CountChar.pione +1 -1
- data/example/SieveOfEratosthenes/SieveOfEratosthenes.pione +39 -38
- data/lib/pione.rb +14 -35
- data/lib/pione/agent/input-generator.rb +38 -40
- data/lib/pione/agent/logger.rb +52 -19
- data/lib/pione/agent/rule-provider.rb +5 -8
- data/lib/pione/agent/task-worker.rb +25 -32
- data/lib/pione/agent/tuple-space-client.rb +22 -14
- data/lib/pione/command.rb +21 -0
- data/lib/pione/command/basic-command.rb +267 -84
- data/lib/pione/command/child-process.rb +21 -18
- data/lib/pione/command/daemon-process.rb +9 -8
- data/lib/pione/command/front-owner-command.rb +8 -25
- data/lib/pione/command/pione-broker.rb +27 -24
- data/lib/pione/command/pione-clean.rb +6 -6
- data/lib/pione/command/pione-client.rb +143 -128
- data/lib/pione/command/pione-log.rb +61 -0
- data/lib/pione/command/pione-relay-account-db.rb +40 -38
- data/lib/pione/command/pione-relay-client-db.rb +38 -42
- data/lib/pione/command/pione-relay.rb +19 -20
- data/lib/pione/command/pione-syntax-checker.rb +70 -45
- data/lib/pione/command/pione-task-worker.rb +56 -66
- data/lib/pione/command/pione-tuple-space-provider.rb +36 -45
- data/lib/pione/command/pione-tuple-space-receiver.rb +34 -32
- data/lib/pione/command/pione-tuple-space-viewer.rb +63 -47
- data/lib/pione/location.rb +10 -0
- data/lib/pione/location/basic-location.rb +272 -0
- data/lib/pione/location/dropbox-location.rb +139 -0
- data/lib/pione/location/ftp-location.rb +156 -0
- data/lib/pione/location/local-location.rb +116 -0
- data/lib/pione/log.rb +10 -0
- data/lib/pione/log/domain-info.rb +72 -0
- data/lib/pione/log/process-log.rb +176 -0
- data/lib/pione/log/process-record.rb +189 -0
- data/lib/pione/log/xes-log.rb +105 -0
- data/lib/pione/model/assignment.rb +88 -80
- data/lib/pione/model/binary-operator.rb +74 -68
- data/lib/pione/model/block.rb +218 -207
- data/lib/pione/model/boolean.rb +123 -112
- data/lib/pione/model/call-rule.rb +72 -65
- data/lib/pione/model/data-expr.rb +596 -290
- data/lib/pione/model/float.rb +108 -103
- data/lib/pione/model/integer.rb +133 -129
- data/lib/pione/model/message.rb +79 -72
- data/lib/pione/model/package.rb +42 -38
- data/lib/pione/model/parameters.rb +265 -236
- data/lib/pione/model/rule-expr.rb +247 -242
- data/lib/pione/model/rule-io.rb +137 -133
- data/lib/pione/model/rule.rb +307 -292
- data/lib/pione/model/string.rb +110 -99
- data/lib/pione/model/variable-table.rb +300 -271
- data/lib/pione/model/variable.rb +88 -83
- data/lib/pione/option.rb +13 -0
- data/lib/pione/option/child-process-option.rb +19 -0
- data/lib/pione/{command-option → option}/common-option.rb +6 -5
- data/lib/pione/option/option-interface.rb +73 -0
- data/lib/pione/{command-option → option}/presence-notifier-option.rb +4 -3
- data/lib/pione/option/task-worker-owner-option.rb +24 -0
- data/lib/pione/{command-option → option}/tuple-space-provider-option.rb +6 -4
- data/lib/pione/option/tuple-space-provider-owner-option.rb +18 -0
- data/lib/pione/option/tuple-space-receiver-option.rb +8 -0
- data/lib/pione/parser/common-parser.rb +3 -2
- data/lib/pione/parser/expr-parser.rb +6 -1
- data/lib/pione/patch/em-ftpd-patch.rb +21 -0
- data/lib/pione/patch/rinda-patch.rb +31 -23
- data/lib/pione/rule-handler/action-handler.rb +35 -25
- data/lib/pione/rule-handler/basic-handler.rb +92 -18
- data/lib/pione/rule-handler/flow-handler.rb +104 -98
- data/lib/pione/rule-handler/root-handler.rb +11 -0
- data/lib/pione/system/common.rb +10 -0
- data/lib/pione/system/file-cache.rb +103 -84
- data/lib/pione/system/global.rb +67 -12
- data/lib/pione/system/init.rb +20 -0
- data/lib/pione/transformer/expr-transformer.rb +6 -1
- data/lib/pione/tuple-space/data-finder.rb +33 -6
- data/lib/pione/tuple-space/tuple-space-receiver.rb +4 -3
- data/lib/pione/tuple-space/tuple-space-server-interface.rb +58 -13
- data/lib/pione/tuple-space/tuple-space-server.rb +13 -11
- data/lib/pione/tuple-space/update-criteria.rb +8 -7
- data/lib/pione/tuple/base-location-tuple.rb +9 -0
- data/lib/pione/tuple/basic-tuple.rb +7 -7
- data/lib/pione/tuple/data-tuple.rb +5 -2
- data/lib/pione/tuple/lift-tuple.rb +14 -0
- data/lib/pione/tuple/rule-tuple.rb +1 -1
- data/lib/pione/tuple/task-tuple.rb +5 -1
- data/lib/pione/version.rb +1 -1
- data/pione.gemspec +5 -1
- data/test/location/spec_basic-location.rb +35 -0
- data/test/location/spec_ftp-location.rb +100 -0
- data/test/location/spec_local-location.rb +99 -0
- data/test/log/data/sample.log +1003 -0
- data/test/log/spec_xes-log.rb +11 -0
- data/test/model/spec_data-expr.rb +249 -6
- data/test/model/spec_data-expr.yml +45 -0
- data/test/parser/spec_expr-parser.yml +4 -0
- data/test/spec_data-finder.rb +13 -7
- data/test/spec_data-finder.yml +42 -13
- data/test/system/spec_file-cache.rb +39 -0
- data/test/test-util.rb +226 -1
- data/test/transformer/spec_expr-transformer.rb +12 -1
- metadata +107 -24
- data/bin/pione-search-log +0 -30
- data/lib/pione/command-option/basic-option.rb +0 -42
- data/lib/pione/command-option/child-process-option.rb +0 -17
- data/lib/pione/command-option/daemon-option.rb +0 -12
- data/lib/pione/command-option/task-worker-owner-option.rb +0 -17
- data/lib/pione/command-option/tuple-space-provider-owner-option.rb +0 -16
- data/lib/pione/command-option/tuple-space-receiver-option.rb +0 -12
- data/lib/pione/command/tuple-space-provider-owner.rb +0 -6
- data/lib/pione/resource/basic-resource.rb +0 -92
- data/lib/pione/resource/dropbox-resource.rb +0 -106
- data/lib/pione/resource/ftp.rb +0 -84
- data/lib/pione/resource/local.rb +0 -113
- data/lib/pione/tuple/base-uri-tuple.rb +0 -9
- data/lib/pione/tuple/shift-tuple.rb +0 -13
- data/lib/pione/util/log.rb +0 -79
- data/test/spec_resource.rb +0 -73
@@ -0,0 +1,116 @@
|
|
1
|
+
module Pione
|
2
|
+
module Location
|
3
|
+
# LocalLocation represents local disk locations.
|
4
|
+
class LocalLocation < BasicLocation
|
5
|
+
set_scheme "local"
|
6
|
+
|
7
|
+
def initialize(uri)
|
8
|
+
super(uri.absolute)
|
9
|
+
end
|
10
|
+
|
11
|
+
def rebuild(path)
|
12
|
+
scheme = @uri.scheme
|
13
|
+
path = path.expand_path.to_s
|
14
|
+
Location["%s:%s" % [scheme, path]]
|
15
|
+
end
|
16
|
+
|
17
|
+
def create(data)
|
18
|
+
if @path.exist?
|
19
|
+
raise ExistAlready.new(self)
|
20
|
+
else
|
21
|
+
@path.dirname.mkpath unless @path.dirname.exist?
|
22
|
+
@path.open("w+"){|f| f.write(data)}
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def append(data)
|
27
|
+
if exist?
|
28
|
+
update(read + data)
|
29
|
+
else
|
30
|
+
create(data)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def read
|
35
|
+
@path.exist? ? @path.read : (raise NotFound.new(self))
|
36
|
+
end
|
37
|
+
|
38
|
+
def update(data)
|
39
|
+
if @path.exist?
|
40
|
+
@path.open("w+"){|file| file.write(data)}
|
41
|
+
else
|
42
|
+
raise NotFound.new(@uri)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def delete
|
47
|
+
@path.delete if @path.exist?
|
48
|
+
end
|
49
|
+
|
50
|
+
def mtime
|
51
|
+
@path.exist? ? @path.mtime : (raise NotFound.new(self))
|
52
|
+
end
|
53
|
+
|
54
|
+
def size
|
55
|
+
@path.exist? ? @path.size : (raise NotFound.new(self))
|
56
|
+
end
|
57
|
+
|
58
|
+
def entries
|
59
|
+
@path.entries.select{|entry| (@path + entry).file?}.map do |entry|
|
60
|
+
Location["local:%s" % (@path + entry).expand_path]
|
61
|
+
end
|
62
|
+
rescue Errno::ENOENT
|
63
|
+
raise NotFound.new(self)
|
64
|
+
end
|
65
|
+
|
66
|
+
def file?
|
67
|
+
@path.file?
|
68
|
+
end
|
69
|
+
|
70
|
+
def directory?
|
71
|
+
@path.directory?
|
72
|
+
end
|
73
|
+
|
74
|
+
def exist?
|
75
|
+
@path.exist?
|
76
|
+
end
|
77
|
+
|
78
|
+
def move(dest)
|
79
|
+
raise NotFound.new(self) unless exist?
|
80
|
+
if dest.kind_of?(LocalLocation)
|
81
|
+
dest.path.dirname.mkpath unless dest.path.dirname.exist?
|
82
|
+
FileUtils.mv(@path, dest.path)
|
83
|
+
else
|
84
|
+
copy(dest)
|
85
|
+
delete
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
def copy(dest)
|
90
|
+
if dest.kind_of?(LocalLocation)
|
91
|
+
dest.path.dirname.mkpath unless dest.path.dirname.exist?
|
92
|
+
IO.copy_stream(@path.open, dest.path)
|
93
|
+
else
|
94
|
+
dest.exist? ? dest.update(read) : dest.create(read)
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
def link(orig)
|
99
|
+
if orig.kind_of?(LocalLocation)
|
100
|
+
@path.make_symlink(orig.path)
|
101
|
+
else
|
102
|
+
orig.copy(self)
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
def turn(dest)
|
107
|
+
if dest.kind_of?(LocalLocation)
|
108
|
+
move(dest)
|
109
|
+
link(dest)
|
110
|
+
else
|
111
|
+
copy(dest)
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
data/lib/pione/log.rb
ADDED
@@ -0,0 +1,72 @@
|
|
1
|
+
module Pione
|
2
|
+
module Log
|
3
|
+
# DomainInfo is a domain log that records domain inputs and parameters.
|
4
|
+
class DomainInfo
|
5
|
+
# @return [Location::BasicLocation]
|
6
|
+
# domain's location
|
7
|
+
attr_reader :domain_location
|
8
|
+
|
9
|
+
# @return [Hash{String => String}]
|
10
|
+
# record table
|
11
|
+
attr_reader :record
|
12
|
+
|
13
|
+
# @param handler [RuleHandler::BasicHandler]
|
14
|
+
# rule handler
|
15
|
+
def initialize(handler)
|
16
|
+
@domain_location = handler.domain_location
|
17
|
+
@record = {
|
18
|
+
"uname" => `uname -a`.chomp,
|
19
|
+
"params" => handler.params.textize,
|
20
|
+
"original_params" => handler.original_params.textize,
|
21
|
+
"inputs" => inputs_string(handler.inputs),
|
22
|
+
"domain" => handler.domain,
|
23
|
+
"domain_location" => @domain_location.uri.to_s,
|
24
|
+
"task_id" => handler.task_id.to_s,
|
25
|
+
"dry_run" => handler.dry_run.to_s
|
26
|
+
}
|
27
|
+
end
|
28
|
+
|
29
|
+
# Save domain information file.
|
30
|
+
#
|
31
|
+
# @return [void]
|
32
|
+
def save
|
33
|
+
text = "== %s\n\n" % Time.now
|
34
|
+
text << @record.map{|key, val| "- %s: %s" % [key,val]}.join("\n")
|
35
|
+
text << "\n\n"
|
36
|
+
(@domain_location + ".domain_info").append(text)
|
37
|
+
end
|
38
|
+
|
39
|
+
private
|
40
|
+
|
41
|
+
# Build a record string for inputs.
|
42
|
+
#
|
43
|
+
# @param inputs [Array<Tuple::DataTuple>]
|
44
|
+
# input tuples
|
45
|
+
# @return [String]
|
46
|
+
# a record string
|
47
|
+
def inputs_string(inputs)
|
48
|
+
"\n%s" % inputs.map.with_index(1) do |input, i|
|
49
|
+
if input.kind_of?(Array)
|
50
|
+
input.map{|_input| input_data_string(_input, i)}.join("\n")
|
51
|
+
else
|
52
|
+
input_data_string(input, i)
|
53
|
+
end
|
54
|
+
end.join("\n")
|
55
|
+
end
|
56
|
+
|
57
|
+
# Build a data tuple string.
|
58
|
+
#
|
59
|
+
# @param input [Tuple::DataTuple]
|
60
|
+
# data tuple
|
61
|
+
# @param i [Integer]
|
62
|
+
# index number
|
63
|
+
def input_data_string(input, i)
|
64
|
+
i = i.to_s
|
65
|
+
sp1 = " "*4
|
66
|
+
sp2 = " "*(6+i.size)
|
67
|
+
args = [sp1, i, input.name, sp2, input.location.uri, sp2, input.timestamp]
|
68
|
+
"%s%s. %s,\n%s%s,\n%s%s" % args
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
@@ -0,0 +1,176 @@
|
|
1
|
+
module Pione
|
2
|
+
module Log
|
3
|
+
# ProcessLog represents process log records of PIONE.
|
4
|
+
class ProcessLog
|
5
|
+
# formatter table
|
6
|
+
@format = {}
|
7
|
+
|
8
|
+
class << self
|
9
|
+
# Set formatter name of this class.
|
10
|
+
#
|
11
|
+
# @param name [Symbol]
|
12
|
+
# formatter name
|
13
|
+
# @return [void]
|
14
|
+
def set_format_name(name)
|
15
|
+
ProcessLog.instance_variable_get(:@format)[name] = self
|
16
|
+
end
|
17
|
+
|
18
|
+
# Return the named formatter class.
|
19
|
+
#
|
20
|
+
# @param name [Symbol]
|
21
|
+
# formatter name
|
22
|
+
# @return [Class]
|
23
|
+
# formatter class
|
24
|
+
def [](name)
|
25
|
+
ProcessLog.instance_variable_get(:@format)[name]
|
26
|
+
end
|
27
|
+
|
28
|
+
# Read log files and return the process log.
|
29
|
+
#
|
30
|
+
# @param location [Location]
|
31
|
+
# path of process log file
|
32
|
+
# @return [ProcessLogFile]
|
33
|
+
# log object
|
34
|
+
def read(location)
|
35
|
+
if location.file?
|
36
|
+
read_file(location)
|
37
|
+
else
|
38
|
+
read_directory(location)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
# Set record filter.
|
43
|
+
#
|
44
|
+
# @yield block
|
45
|
+
def set_filter(&block)
|
46
|
+
@filter_block = block
|
47
|
+
end
|
48
|
+
|
49
|
+
attr_reader :filter_block
|
50
|
+
|
51
|
+
private
|
52
|
+
|
53
|
+
# Read records from the log file at the location.
|
54
|
+
#
|
55
|
+
# @param location [Location::BasicLocation]
|
56
|
+
# log location
|
57
|
+
def read_file(location)
|
58
|
+
cache = Location[Temppath.create]
|
59
|
+
cache.create(location.read)
|
60
|
+
cache.path.each_line.map do |line|
|
61
|
+
JSON.parse(line).inject({}) do |data, pair|
|
62
|
+
data[pair[0].to_sym] = pair[1]
|
63
|
+
data
|
64
|
+
end.tap do |table|
|
65
|
+
break ProcessRecord.build(table)
|
66
|
+
end
|
67
|
+
end.tap do |records|
|
68
|
+
break new([ProcessLogBundle.new(records)])
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
# Read records from log files in directory at the location.
|
73
|
+
#
|
74
|
+
# @param location [Location::BasicLocation]
|
75
|
+
# log directory location
|
76
|
+
def read_directory(location)
|
77
|
+
location.entries.inject(new([])) do |formatter, entry|
|
78
|
+
if /pione_\d{14}\.log/.match(entry.path.basename.to_s)
|
79
|
+
new(formatter.bundles + read_file(entry).bundles)
|
80
|
+
else
|
81
|
+
formatter
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
forward :@records, :map
|
88
|
+
|
89
|
+
# @return [Array<ProcessRcord>]
|
90
|
+
# records of the log
|
91
|
+
attr_reader :records
|
92
|
+
|
93
|
+
# @param records [Array<ProcessRecord>]
|
94
|
+
# log records
|
95
|
+
def initialize(records)
|
96
|
+
@records = records.select {|record| self.class.filter_block.call(record)}
|
97
|
+
end
|
98
|
+
|
99
|
+
# Return the record table grouped by the key.
|
100
|
+
#
|
101
|
+
# @return [Hash{String => Array<ProcessRecord>}]
|
102
|
+
# grouping records table
|
103
|
+
def group_by(key)
|
104
|
+
@records.inject({}) do |table, record|
|
105
|
+
table[record.send(key)] ||= []
|
106
|
+
table.tap {|x| x[record.send(key)] << record}
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
# ProcessLogFormatter is a basic class for fomatting process logs.
|
112
|
+
class ProcessLogFormatter < ProcessLog
|
113
|
+
# @return [Array<ProcessBunle>]
|
114
|
+
# target logs that we format
|
115
|
+
attr_reader :bundles
|
116
|
+
|
117
|
+
# @param bundles [Array<ProcessLogBundle>]
|
118
|
+
# log bundles
|
119
|
+
def initialize(bundles)
|
120
|
+
@bundles = bundles
|
121
|
+
end
|
122
|
+
|
123
|
+
# Format bundle logs.
|
124
|
+
#
|
125
|
+
# @return [String]
|
126
|
+
# result string
|
127
|
+
def format(trace_filters=[])
|
128
|
+
raise NotImplementedError
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
# ProcessLogFormatError is raised when formatter cannot format some objects.
|
133
|
+
class ProcessLogFormatError < StandardError
|
134
|
+
# @param object [Object]
|
135
|
+
# the object that we cannnot format
|
136
|
+
def initialize(object)
|
137
|
+
@object = object
|
138
|
+
end
|
139
|
+
|
140
|
+
# @api private
|
141
|
+
def message
|
142
|
+
"not formattable: %s" % @object.inspect
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
# ProcessLogBundle is a bundle of raw logs.
|
147
|
+
class ProcessLogBundle
|
148
|
+
attr_reader :agent_activity_log
|
149
|
+
attr_reader :rule_process_log
|
150
|
+
attr_reader :task_process_log
|
151
|
+
|
152
|
+
# @param records [Array<ProcessRecord>]
|
153
|
+
# log records
|
154
|
+
def initialize(records)
|
155
|
+
@agent_activity_log = AgentActivityLog.new(records)
|
156
|
+
@rule_process_log = RuleProcessLog.new(records)
|
157
|
+
@task_process_log = TaskProcessLog.new(records)
|
158
|
+
end
|
159
|
+
end
|
160
|
+
|
161
|
+
# AgentActivityLog is a set of records written about agent activities.
|
162
|
+
class AgentActivityLog < ProcessLog
|
163
|
+
set_filter {|record| record.type == :agent_activity}
|
164
|
+
end
|
165
|
+
|
166
|
+
# RuleProcessLog is a set of records written about details of rule process.
|
167
|
+
class RuleProcessLog < ProcessLog
|
168
|
+
set_filter {|record| record.type == :rule_process}
|
169
|
+
end
|
170
|
+
|
171
|
+
# TaskProcessLog is a set of records written about details of task process.
|
172
|
+
class TaskProcessLog < ProcessLog
|
173
|
+
set_filter {|record| record.type == :task_process}
|
174
|
+
end
|
175
|
+
end
|
176
|
+
end
|
@@ -0,0 +1,189 @@
|
|
1
|
+
module Pione
|
2
|
+
module Log
|
3
|
+
# UnknownProcessRecordType is raised when we find unknown process types.
|
4
|
+
class UnknownProcessRecordType < StandardError
|
5
|
+
# @param type [Symbol]
|
6
|
+
# type name
|
7
|
+
def initialize(type)
|
8
|
+
@type = type
|
9
|
+
end
|
10
|
+
|
11
|
+
# @api private
|
12
|
+
def message
|
13
|
+
'Unknown process type "%s"' % @type
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
# ProcessRecord is a class that represents records of process log. Records
|
18
|
+
# are in tuple spaces and handled by PIONE's logger agent.
|
19
|
+
class ProcessRecord
|
20
|
+
# known process record types and classes
|
21
|
+
TYPE_TABLE = {}
|
22
|
+
|
23
|
+
class << self
|
24
|
+
# @return [String]
|
25
|
+
# record type
|
26
|
+
attr_reader :type
|
27
|
+
|
28
|
+
# @return [Array<Symbol>]
|
29
|
+
# field names
|
30
|
+
attr_reader :fields
|
31
|
+
|
32
|
+
# Build a new record from hash table.
|
33
|
+
#
|
34
|
+
# @param hash [Hash{Symbol=>String}]
|
35
|
+
def build(hash)
|
36
|
+
if klass = TYPE_TABLE[hash[:type].to_sym]
|
37
|
+
klass.new(hash)
|
38
|
+
else
|
39
|
+
raise UnknownProcessRecordType.new(hash[:type])
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
private
|
44
|
+
|
45
|
+
# Set type of the record class.
|
46
|
+
def set_type(name)
|
47
|
+
@type = name
|
48
|
+
ProcessRecord::TYPE_TABLE[name] = self
|
49
|
+
end
|
50
|
+
|
51
|
+
# Declare to append the named field into records.
|
52
|
+
#
|
53
|
+
# @param name [Symbol]
|
54
|
+
# field name of the record
|
55
|
+
# @return [void]
|
56
|
+
def field(name)
|
57
|
+
unless (@fields ||= []).include?(name)
|
58
|
+
@fields << name
|
59
|
+
|
60
|
+
define_method(name) do
|
61
|
+
instance_variable_get("@%s" % name)
|
62
|
+
end
|
63
|
+
|
64
|
+
define_method("%s=" % name) do |val|
|
65
|
+
val = Time.parse(val) if name == :timestamp and val.kind_of?(String)
|
66
|
+
instance_variable_set("@%s" % name, val)
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
# @api private
|
72
|
+
def inherited(klass)
|
73
|
+
klass.instance_variable_set(:@fields, @fields.clone)
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
# @!attribute [rw]
|
78
|
+
# @return [Time]
|
79
|
+
# record timestamp
|
80
|
+
field :timestamp
|
81
|
+
|
82
|
+
# @!attribute [rw]
|
83
|
+
# @return [String]
|
84
|
+
# transition name
|
85
|
+
field :transition
|
86
|
+
|
87
|
+
forward! :class, :type, :fields
|
88
|
+
|
89
|
+
# Create a new process log record.
|
90
|
+
#
|
91
|
+
# @param data [Hash{String => Object}]
|
92
|
+
# log content
|
93
|
+
def initialize(data={})
|
94
|
+
data.each {|key, val| send("%s=" % key, val) unless key == :type}
|
95
|
+
end
|
96
|
+
|
97
|
+
# Create a copy of the record and merge the data into it.
|
98
|
+
#
|
99
|
+
# @return [ProcessRecord]
|
100
|
+
# new merged record
|
101
|
+
def merge(data)
|
102
|
+
ProcessRecord.build(to_hash).tap do |record|
|
103
|
+
data.each do |key, val|
|
104
|
+
record.send("%s=" % key, val)
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
# Format as JSON string.
|
110
|
+
#
|
111
|
+
# @return [String]
|
112
|
+
# JSON string
|
113
|
+
def format
|
114
|
+
JSON.dump(to_hash)
|
115
|
+
end
|
116
|
+
|
117
|
+
# Convert record into a hash table.
|
118
|
+
#
|
119
|
+
# @return [Hash]
|
120
|
+
# hash table representation of the record
|
121
|
+
def to_hash
|
122
|
+
fields.inject({type: type}) do |table, name|
|
123
|
+
table.tap do
|
124
|
+
if val = send(name)
|
125
|
+
val = val.iso8601(3) if name == :timestamp
|
126
|
+
table[name] = val
|
127
|
+
end
|
128
|
+
end
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
# @api private
|
133
|
+
def to_json(*args)
|
134
|
+
to_hash.to_json(*args)
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
# CreateChildTaskWorkerProcessRecord represents the event that a task worker
|
139
|
+
# creates the child task worker.
|
140
|
+
class CreateChildTaskWorkerProcessRecord < ProcessRecord
|
141
|
+
set_type :create_child_task_worker
|
142
|
+
field :parent
|
143
|
+
field :child
|
144
|
+
end
|
145
|
+
|
146
|
+
# PutDataProcessRecord represents data uploading to some location.
|
147
|
+
class PutDataProcessRecord < ProcessRecord
|
148
|
+
set_type :put_data
|
149
|
+
field :agent_type
|
150
|
+
field :agent_uuid
|
151
|
+
field :location
|
152
|
+
field :size
|
153
|
+
end
|
154
|
+
|
155
|
+
# AgentActivityProcessRecord represents agent acitivity about state transition.
|
156
|
+
class AgentActivityProcessRecord < ProcessRecord
|
157
|
+
set_type :agent_activity
|
158
|
+
field :agent_type
|
159
|
+
field :agent_uuid
|
160
|
+
field :state
|
161
|
+
end
|
162
|
+
|
163
|
+
# AgentConnectionProcessRecord represents hello and bye message from agents.
|
164
|
+
class AgentConnectionProcessRecord < ProcessRecord
|
165
|
+
set_type :agent_connection
|
166
|
+
field :agent_type
|
167
|
+
field :agent_uuid
|
168
|
+
field :message
|
169
|
+
end
|
170
|
+
|
171
|
+
# RuleProcessRecord represents lifecyles of rule process.
|
172
|
+
class RuleProcessRecord < ProcessRecord
|
173
|
+
set_type :rule_process
|
174
|
+
field :name
|
175
|
+
field :rule_type
|
176
|
+
field :caller
|
177
|
+
end
|
178
|
+
|
179
|
+
# TaskProcessRecord represents lifecyle of task process.
|
180
|
+
class TaskProcessRecord < ProcessRecord
|
181
|
+
set_type :task_process
|
182
|
+
field :name
|
183
|
+
field :rule_name
|
184
|
+
field :rule_type
|
185
|
+
field :inputs
|
186
|
+
field :parameters
|
187
|
+
end
|
188
|
+
end
|
189
|
+
end
|