pione 0.1.2 → 0.1.3

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.
Files changed (122) hide show
  1. data/.gitignore +2 -1
  2. data/History.txt +11 -0
  3. data/LICENSE.txt +1 -1
  4. data/README.md +1 -1
  5. data/bin/pione-log +5 -0
  6. data/example/CountChar/CountChar.pione +1 -1
  7. data/example/SieveOfEratosthenes/SieveOfEratosthenes.pione +39 -38
  8. data/lib/pione.rb +14 -35
  9. data/lib/pione/agent/input-generator.rb +38 -40
  10. data/lib/pione/agent/logger.rb +52 -19
  11. data/lib/pione/agent/rule-provider.rb +5 -8
  12. data/lib/pione/agent/task-worker.rb +25 -32
  13. data/lib/pione/agent/tuple-space-client.rb +22 -14
  14. data/lib/pione/command.rb +21 -0
  15. data/lib/pione/command/basic-command.rb +267 -84
  16. data/lib/pione/command/child-process.rb +21 -18
  17. data/lib/pione/command/daemon-process.rb +9 -8
  18. data/lib/pione/command/front-owner-command.rb +8 -25
  19. data/lib/pione/command/pione-broker.rb +27 -24
  20. data/lib/pione/command/pione-clean.rb +6 -6
  21. data/lib/pione/command/pione-client.rb +143 -128
  22. data/lib/pione/command/pione-log.rb +61 -0
  23. data/lib/pione/command/pione-relay-account-db.rb +40 -38
  24. data/lib/pione/command/pione-relay-client-db.rb +38 -42
  25. data/lib/pione/command/pione-relay.rb +19 -20
  26. data/lib/pione/command/pione-syntax-checker.rb +70 -45
  27. data/lib/pione/command/pione-task-worker.rb +56 -66
  28. data/lib/pione/command/pione-tuple-space-provider.rb +36 -45
  29. data/lib/pione/command/pione-tuple-space-receiver.rb +34 -32
  30. data/lib/pione/command/pione-tuple-space-viewer.rb +63 -47
  31. data/lib/pione/location.rb +10 -0
  32. data/lib/pione/location/basic-location.rb +272 -0
  33. data/lib/pione/location/dropbox-location.rb +139 -0
  34. data/lib/pione/location/ftp-location.rb +156 -0
  35. data/lib/pione/location/local-location.rb +116 -0
  36. data/lib/pione/log.rb +10 -0
  37. data/lib/pione/log/domain-info.rb +72 -0
  38. data/lib/pione/log/process-log.rb +176 -0
  39. data/lib/pione/log/process-record.rb +189 -0
  40. data/lib/pione/log/xes-log.rb +105 -0
  41. data/lib/pione/model/assignment.rb +88 -80
  42. data/lib/pione/model/binary-operator.rb +74 -68
  43. data/lib/pione/model/block.rb +218 -207
  44. data/lib/pione/model/boolean.rb +123 -112
  45. data/lib/pione/model/call-rule.rb +72 -65
  46. data/lib/pione/model/data-expr.rb +596 -290
  47. data/lib/pione/model/float.rb +108 -103
  48. data/lib/pione/model/integer.rb +133 -129
  49. data/lib/pione/model/message.rb +79 -72
  50. data/lib/pione/model/package.rb +42 -38
  51. data/lib/pione/model/parameters.rb +265 -236
  52. data/lib/pione/model/rule-expr.rb +247 -242
  53. data/lib/pione/model/rule-io.rb +137 -133
  54. data/lib/pione/model/rule.rb +307 -292
  55. data/lib/pione/model/string.rb +110 -99
  56. data/lib/pione/model/variable-table.rb +300 -271
  57. data/lib/pione/model/variable.rb +88 -83
  58. data/lib/pione/option.rb +13 -0
  59. data/lib/pione/option/child-process-option.rb +19 -0
  60. data/lib/pione/{command-option → option}/common-option.rb +6 -5
  61. data/lib/pione/option/option-interface.rb +73 -0
  62. data/lib/pione/{command-option → option}/presence-notifier-option.rb +4 -3
  63. data/lib/pione/option/task-worker-owner-option.rb +24 -0
  64. data/lib/pione/{command-option → option}/tuple-space-provider-option.rb +6 -4
  65. data/lib/pione/option/tuple-space-provider-owner-option.rb +18 -0
  66. data/lib/pione/option/tuple-space-receiver-option.rb +8 -0
  67. data/lib/pione/parser/common-parser.rb +3 -2
  68. data/lib/pione/parser/expr-parser.rb +6 -1
  69. data/lib/pione/patch/em-ftpd-patch.rb +21 -0
  70. data/lib/pione/patch/rinda-patch.rb +31 -23
  71. data/lib/pione/rule-handler/action-handler.rb +35 -25
  72. data/lib/pione/rule-handler/basic-handler.rb +92 -18
  73. data/lib/pione/rule-handler/flow-handler.rb +104 -98
  74. data/lib/pione/rule-handler/root-handler.rb +11 -0
  75. data/lib/pione/system/common.rb +10 -0
  76. data/lib/pione/system/file-cache.rb +103 -84
  77. data/lib/pione/system/global.rb +67 -12
  78. data/lib/pione/system/init.rb +20 -0
  79. data/lib/pione/transformer/expr-transformer.rb +6 -1
  80. data/lib/pione/tuple-space/data-finder.rb +33 -6
  81. data/lib/pione/tuple-space/tuple-space-receiver.rb +4 -3
  82. data/lib/pione/tuple-space/tuple-space-server-interface.rb +58 -13
  83. data/lib/pione/tuple-space/tuple-space-server.rb +13 -11
  84. data/lib/pione/tuple-space/update-criteria.rb +8 -7
  85. data/lib/pione/tuple/base-location-tuple.rb +9 -0
  86. data/lib/pione/tuple/basic-tuple.rb +7 -7
  87. data/lib/pione/tuple/data-tuple.rb +5 -2
  88. data/lib/pione/tuple/lift-tuple.rb +14 -0
  89. data/lib/pione/tuple/rule-tuple.rb +1 -1
  90. data/lib/pione/tuple/task-tuple.rb +5 -1
  91. data/lib/pione/version.rb +1 -1
  92. data/pione.gemspec +5 -1
  93. data/test/location/spec_basic-location.rb +35 -0
  94. data/test/location/spec_ftp-location.rb +100 -0
  95. data/test/location/spec_local-location.rb +99 -0
  96. data/test/log/data/sample.log +1003 -0
  97. data/test/log/spec_xes-log.rb +11 -0
  98. data/test/model/spec_data-expr.rb +249 -6
  99. data/test/model/spec_data-expr.yml +45 -0
  100. data/test/parser/spec_expr-parser.yml +4 -0
  101. data/test/spec_data-finder.rb +13 -7
  102. data/test/spec_data-finder.yml +42 -13
  103. data/test/system/spec_file-cache.rb +39 -0
  104. data/test/test-util.rb +226 -1
  105. data/test/transformer/spec_expr-transformer.rb +12 -1
  106. metadata +107 -24
  107. data/bin/pione-search-log +0 -30
  108. data/lib/pione/command-option/basic-option.rb +0 -42
  109. data/lib/pione/command-option/child-process-option.rb +0 -17
  110. data/lib/pione/command-option/daemon-option.rb +0 -12
  111. data/lib/pione/command-option/task-worker-owner-option.rb +0 -17
  112. data/lib/pione/command-option/tuple-space-provider-owner-option.rb +0 -16
  113. data/lib/pione/command-option/tuple-space-receiver-option.rb +0 -12
  114. data/lib/pione/command/tuple-space-provider-owner.rb +0 -6
  115. data/lib/pione/resource/basic-resource.rb +0 -92
  116. data/lib/pione/resource/dropbox-resource.rb +0 -106
  117. data/lib/pione/resource/ftp.rb +0 -84
  118. data/lib/pione/resource/local.rb +0 -113
  119. data/lib/pione/tuple/base-uri-tuple.rb +0 -9
  120. data/lib/pione/tuple/shift-tuple.rb +0 -13
  121. data/lib/pione/util/log.rb +0 -79
  122. data/test/spec_resource.rb +0 -73
data/.gitignore CHANGED
@@ -11,4 +11,5 @@ vendor/bundle
11
11
  pkg
12
12
  \#*
13
13
  nohup.out
14
- Gemfile.lock
14
+ Gemfile.lock
15
+ gems
data/History.txt CHANGED
@@ -1,5 +1,16 @@
1
1
  # History
2
2
 
3
+ ## 0.1.3(2013/04/XX)
4
+
5
+ * Added new data expression literal "null" for accepting data nonexistence
6
+ * Added new data expression property keyword "neglect" and "care" for the update criterion about data mtime
7
+ * Changed log location to be in output location
8
+ * Changed log format to JSON
9
+ * Added pione-log command that generates agent activity log as XES format
10
+ * Use locations in tuples
11
+ * Enabled to test FTP location handling without setting up FTP server
12
+ * Added the feature to create domain information files(".domain_info")
13
+
3
14
  ## 0.1.2(2013/04/01)
4
15
 
5
16
  * Added shorthand notation for setting parameters
data/LICENSE.txt CHANGED
@@ -1,4 +1,4 @@
1
- Copyright (c) 2012 NaU Data Institute Inc.
1
+ Copyright (c) 2012-2013 NaU Data Institute Inc and contributors.
2
2
 
3
3
  MIT License
4
4
 
data/README.md CHANGED
@@ -84,7 +84,7 @@ because these are patches including original codes:
84
84
 
85
85
  ## Links
86
86
 
87
- * [PIONE project homepage](http://pione.github.com/)
87
+ * [PIONE project homepage](http://pione.github.io/)
88
88
  * [repository on github](https://github.com/pione/pione)
89
89
  * [Yasunaga Laboratory](http://www.yasunaga-lab.bio.kyutech.ac.jp/)
90
90
  * [EOS](http://www.yasunaga-lab.bio.kyutech.ac.jp/Eos/)([ja](http://www.yasunaga-lab.bio.kyutech.ac.jp/EosJ/))
data/bin/pione-log ADDED
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env ruby
2
+ # -*- ruby -*-
3
+
4
+ require 'pione'
5
+ Pione::Command::PioneLog.run
@@ -1,5 +1,5 @@
1
1
  Rule Main
2
- input '*.txt:terminate.cmd'.except('summary.txt').all
2
+ input ('*.txt' or 'terminate.cmd').except('summary.txt').all
3
3
  output '*.count'.all
4
4
  output 'summary.txt'
5
5
  Flow
@@ -1,61 +1,62 @@
1
+ param $MAX := 20
2
+
1
3
  Rule Main
2
- output '*.prime'
3
- param $MAX := 20
4
+ output '*.prime'.all
4
5
  Flow
5
- rule CurrentNumber.params({NUM: 2})
6
- rule Sieve.params({MAX: $MAX, NUM: 2})
6
+ rule Sieve
7
7
  End
8
8
 
9
9
  Rule Sieve
10
- input '{$NUM}.current'
11
- input '*.not_prime'.all or null
12
- output '*.prime'
13
- param $MAX
14
- param $NUM
10
+ input '*-*.not_prime'.all or null
11
+ output '*.current'.all or '*.prime'.all
12
+ param $NUM := 2
15
13
  Flow
16
- if $NUM <= $MAX
17
- if $*.include?($NUM.as_string).not
18
- rule CreateNotPrimeAll.params({MAX: $MAX, NUM: $NUM})
19
- rule CreatePrime.params({NUM: $NUM})
14
+ $NEXT_NUM := $NUM + 1
15
+ $NEXT_RULE := Sieve {NUM: $NEXT_NUM}
16
+ rule Current {N: $NUM}
17
+ if not :: $*.as_data_expr.match?($NUM.as_string)
18
+ rule CreatePrime {N: $NUM}
19
+ if ($NUM * $NUM) <= $MAX
20
+ rule CreateNotPrimeAll {P: $NUM} >>> $NEXT_RULE
20
21
  else
21
- rule CurrentNumber.params({NUM: $NUM + 1})
22
+ rule $NEXT_RULE
23
+ end
24
+ else
25
+ if $NEXT_NUM <= $MAX
26
+ rule $NEXT_RULE
22
27
  end
23
- rule Sieve.params({MAX: $MAX, NUM: $NUM + 1})
24
28
  end
25
29
  End
26
30
 
27
- Rule CurrentNumber
28
- output '{$NUM}.current'
29
- param $NUM
30
- Action
31
- touch {$NUM}.current
32
- End
33
-
34
31
  Rule CreateNotPrimeAll
35
- output '*.not_prime'
36
- output '{$NUM + 1}.current'
37
- param $MAX
38
- param $NUM
39
- param $i := 2
32
+ output '*-{$P}.not_prime'.all
33
+ param $P
34
+ param $INDEX := 2
40
35
  Flow
41
- if $NUM * ($i + 1) <= $MAX
42
- rule CreateNotPrimeAll.params({MAX: $MAX, NUM: $NUM, i: $i + 1})
36
+ if ($P * ($INDEX + 1)) <= $MAX
37
+ rule CreateNotPrimeAll {P: $P, INDEX: $INDEX + 1}
43
38
  end
44
- rule CreateNotPrime.params({NUM: $NUM * $i})
45
- rule CurrentNumber.params({NUM: $NUM + 1})
39
+ rule CreateNotPrime {P: $P, N: $P * $INDEX}
46
40
  End
47
41
 
48
42
  Rule CreateNotPrime
49
- output '{$NUM}.not_prime'
50
- param $NUM
43
+ output '{$N}-{$P}.not_prime'
44
+ param $P
45
+ param $N
51
46
  Action
52
- touch {$NUM}.not_prime
53
- end
47
+ touch {$N}-{$P}.not_prime
48
+ End
54
49
 
55
50
  Rule CreatePrime
56
- output '{$NUM}.prime'
57
- param $NUM
51
+ output '{$N}.prime'
52
+ param $N
58
53
  Action
59
- touch {$NUM}.prime
54
+ touch {$N}.prime
60
55
  End
61
56
 
57
+ Rule Current
58
+ output '{$N}.current'
59
+ param $N
60
+ Action
61
+ touch {$N}.current
62
+ End
data/lib/pione.rb CHANGED
@@ -5,7 +5,7 @@ require 'bundler/setup'
5
5
  require 'set'
6
6
  require 'socket'
7
7
  require 'digest'
8
- require 'forwardable'
8
+ require 'forwardablex'
9
9
  require 'socket'
10
10
  require 'drb/drb'
11
11
  require 'drb/ssl'
@@ -22,6 +22,7 @@ require 'pathname'
22
22
  require 'time'
23
23
  require 'etc'
24
24
  require 'json'
25
+ require 'rexml/document'
25
26
 
26
27
  require 'uuidtools'
27
28
  require 'parslet'
@@ -31,6 +32,8 @@ require 'highline'
31
32
  require 'dropbox_sdk'
32
33
  require 'hamster'
33
34
  require 'naming'
35
+ require 'temppath'
36
+ require 'xes'
34
37
 
35
38
  #
36
39
  # load pione
@@ -43,10 +46,12 @@ require 'pione/version'
43
46
  require 'pione/util/misc'
44
47
  require 'pione/util/terminal'
45
48
  require 'pione/util/console-message'
46
- require 'pione/util/log'
47
49
  require 'pione/util/waiter-table'
48
50
  require 'pione/util/error-report'
49
51
 
52
+ # log
53
+ require 'pione/log'
54
+
50
55
  # patch
51
56
  require 'pione/patch/array-patch'
52
57
  require 'pione/patch/drb-patch'
@@ -73,6 +78,9 @@ require 'pione/uri-scheme/local-scheme'
73
78
  require 'pione/uri-scheme/dropbox-scheme'
74
79
  require 'pione/uri-scheme/broadcast-scheme'
75
80
 
81
+ # location
82
+ require 'pione/location'
83
+
76
84
  # relay
77
85
  require 'pione/relay/transmitter-socket'
78
86
  require 'pione/relay/trampoline'
@@ -111,7 +119,7 @@ require 'pione/tuple/agent-tuple'
111
119
  require 'pione/tuple/data-tuple'
112
120
  require 'pione/tuple/finished-tuple'
113
121
  require 'pione/tuple/process-info-tuple'
114
- require 'pione/tuple/shift-tuple'
122
+ require 'pione/tuple/lift-tuple'
115
123
  require 'pione/tuple/working-tuple'
116
124
  require 'pione/tuple/attribute-tuple'
117
125
  require 'pione/tuple/bye-tuple'
@@ -119,7 +127,7 @@ require 'pione/tuple/dry-run-tuple'
119
127
  require 'pione/tuple/foreground-tuple'
120
128
  require 'pione/tuple/request-rule-tuple'
121
129
  require 'pione/tuple/task-tuple'
122
- require 'pione/tuple/base-uri-tuple'
130
+ require 'pione/tuple/base-location-tuple'
123
131
  require 'pione/tuple/command-tuple'
124
132
  require 'pione/tuple/exception-tuple'
125
133
  require 'pione/tuple/log-tuple'
@@ -150,12 +158,6 @@ require 'pione/parser/document-parser'
150
158
  # transformer
151
159
  require 'pione/transformer'
152
160
 
153
- # resource
154
- require 'pione/resource/basic-resource'
155
- require 'pione/resource/local'
156
- require 'pione/resource/ftp'
157
- require 'pione/resource/dropbox-resource'
158
-
159
161
  # rule-handler
160
162
  require 'pione/rule-handler/basic-handler'
161
163
  require 'pione/rule-handler/flow-handler'
@@ -188,33 +190,10 @@ require 'pione/front/tuple-space-receiver-front'
188
190
  require 'pione/front/relay-front'
189
191
 
190
192
  # command-option
191
- require 'pione/command-option/basic-option'
192
- require 'pione/command-option/common-option'
193
- require 'pione/command-option/daemon-option'
194
- require 'pione/command-option/child-process-option'
195
- require 'pione/command-option/presence-notifier-option'
196
- require 'pione/command-option/tuple-space-provider-option'
197
- require 'pione/command-option/tuple-space-provider-owner-option'
198
- require 'pione/command-option/tuple-space-receiver-option'
199
- require 'pione/command-option/task-worker-owner-option'
193
+ require 'pione/option'
200
194
 
201
195
  # command
202
- require 'pione/command/basic-command'
203
- require 'pione/command/front-owner-command'
204
- require 'pione/command/daemon-process'
205
- require 'pione/command/child-process'
206
- require 'pione/command/pione-client'
207
- require 'pione/command/pione-task-worker'
208
- require 'pione/command/pione-broker'
209
- require 'pione/command/pione-tuple-space-provider'
210
- require 'pione/command/pione-tuple-space-receiver'
211
- require 'pione/command/pione-tuple-space-viewer'
212
- require 'pione/command/pione-relay'
213
- require 'pione/command/pione-relay-client-db'
214
- require 'pione/command/pione-relay-account-db'
215
- require 'pione/command/pione-clean'
216
- require 'pione/command/pione-syntax-checker'
217
-
196
+ require 'pione/command'
218
197
 
219
198
  #
220
199
  # other settings
@@ -16,7 +16,7 @@ module Pione
16
16
  @tuple_space_server.now
17
17
  end
18
18
 
19
- # Generates an input.
19
+ # Generate an input.
20
20
  def generate
21
21
  raise RuntimeError
22
22
  end
@@ -29,22 +29,18 @@ module Pione
29
29
  end
30
30
  end
31
31
 
32
- # Directory based generator.
32
+ # DirGeneratorMethod is a directory based generator.
33
33
  class DirGeneratorMethod < GeneratorMethod
34
34
  # Create a generator.
35
- # @param [TupleSpaceServer] ts_server
35
+ #
36
+ # @param tuple_space_server [TupleSpaceServer]
36
37
  # tuple space server
37
- # @param [URI] dir_path
38
- # directory URI for loading target
39
- def initialize(ts_server, dir_path)
40
- raise TypeError.new(dir_path) unless dir_path.kind_of?(URI) or dir_path.nil?
41
- super(ts_server)
42
- @dir_path = dir_path
43
- if dir_path
44
- @gen = Resource[@dir_path].entries.to_enum
45
- else
46
- @gen = [].each
47
- end
38
+ # @param dir [BasicLocation]
39
+ # input directory location
40
+ def initialize(tuple_space_server, dir)
41
+ raise Argument.new(dir) unless dir.kind_of?(Location::BasicLocation) or dir.nil?
42
+ super(tuple_space_server)
43
+ @gen = dir ? dir.entries.to_enum : [].each
48
44
  end
49
45
 
50
46
  def generate
@@ -55,10 +51,10 @@ module Pione
55
51
 
56
52
  # StreamGeneratorMethod handles stream inputs.
57
53
  class StreamGeneratorMethod < GeneratorMethod
58
- def initialize(ts_server, dir_path)
59
- raise TypeError.new(dir_path) unless dir_path.kind_of?(URI) or dir_path.nil?
54
+ def initialize(ts_server, dir)
55
+ raise TypeError.new(dir) unless dir.kind_of?(Location) or dir.nil?
60
56
  super(ts_server)
61
- @dir_path = dir_path
57
+ @dir = dir
62
58
  @table = Hash.new
63
59
  init
64
60
  end
@@ -78,11 +74,7 @@ module Pione
78
74
  #
79
75
  # @return [void]
80
76
  def init
81
- if @dir_path
82
- @gen = Resource[@dir_path].entries.to_enum
83
- else
84
- @gen = [].each
85
- end
77
+ @gen = dir ? @dir.entries.to_enum : [].each
86
78
  end
87
79
 
88
80
  # @api private
@@ -102,11 +94,6 @@ module Pione
102
94
  end
103
95
  end
104
96
 
105
- # Create a input generator agent by simple method.
106
- def self.start_by_simple(ts_server, *args)
107
- start(ts_server, SimpleGeneratorMethod.new(ts_server, ts_server.base_uri, *args))
108
- end
109
-
110
97
  # Create a input generator agent by directory method.
111
98
  def self.start_by_dir(ts_server, *args)
112
99
  start(ts_server, DirGeneratorMethod.new(ts_server, *args))
@@ -121,8 +108,7 @@ module Pione
121
108
  define_state :sleeping
122
109
  define_state :stop_iteration
123
110
 
124
- define_state_transition :initialized => :reading_base_uri
125
- define_state_transition :reading_base_uri => :generating
111
+ define_state_transition :initialized => :generating
126
112
  define_state_transition :generating => :generating
127
113
  define_state_transition :stop_iteration => lambda{|agent, res|
128
114
  agent.stream? ? :sleeping : :terminated
@@ -148,26 +134,38 @@ module Pione
148
134
 
149
135
  private
150
136
 
151
- def transit_to_reading_base_uri
152
- @base_uri = read(Tuple[:base_uri].any).uri
137
+ def transit_to_initialized
138
+ @base_location = base_location
153
139
  end
154
140
 
155
141
  # State generating generates a data from generator and puts it into tuple
156
142
  # space.
157
143
  def transit_to_generating
158
144
  if input = @generator.generate
145
+ # put into history
159
146
  @inputs << input
160
- # log
161
- log do |msg|
162
- msg.add_record(agent_type, "action", "generate_input_data")
163
- msg.add_record(agent_type, "uuid", uuid)
164
- msg.add_record(agent_type, "object", input.name)
147
+
148
+ # build original location
149
+ orig_location = Location[input.uri]
150
+
151
+ # build input location
152
+ input_location = @base_location + File.join("input", input.name)
153
+
154
+ # make process log record
155
+ record = Log::PutDataProcessRecord.new.tap do |record|
156
+ record.agent_type = agent_type
157
+ record.agent_uuid = uuid
158
+ record.location = input_location
159
+ record.size = orig_location.size
165
160
  end
161
+
166
162
  # upload the file
167
- input_uri = @base_uri + File.join("input", input.name)
168
- Resource[input_uri].create(Resource[input.uri].read)
169
- # make the tuple
170
- write(Tuple[:data].new(DOMAIN, input.name, input_uri, input.time))
163
+ with_process_log(record) do
164
+ orig_location.copy(input_location)
165
+ end
166
+
167
+ # put data tuple into tuple space
168
+ write(Tuple[:data].new(DOMAIN, input.name, input_location, input.time))
171
169
  end
172
170
  end
173
171
 
@@ -1,17 +1,36 @@
1
1
  module Pione
2
2
  module Agent
3
- # Logger is an agent for logging in tuple space.
3
+ # Logger is an agent for logging processings in tuple space.
4
4
  class Logger < TupleSpaceClient
5
5
  set_agent_type :logger
6
6
 
7
- def initialize(tuple_space_server, out=$stdout)
7
+ # @return [BasicLocation]
8
+ attr_reader :location
9
+
10
+ # @return [Pathname]
11
+ attr_reader :out
12
+
13
+ # @return [Array<Log::ProcessRecord>]
14
+ attr_reader :records
15
+
16
+ # Create a logger agent.
17
+ #
18
+ # @param tuple_space_server [TupleSpaceServer]
19
+ # tuple space server
20
+ # @param location [BasicLocation]
21
+ # the path to store log records
22
+ def initialize(tuple_space_server, location)
8
23
  super(tuple_space_server)
9
- @out = out
10
- @logs = []
24
+ @location = location
25
+ @temporary = Location[Pione.temporary_path(@location.basename)]
26
+ @out = @temporary.path.open("w+")
27
+ @records = []
11
28
  end
12
29
 
30
+ define_state :initialized
13
31
  define_state :take
14
32
  define_state :store
33
+ define_state :terminated
15
34
 
16
35
  define_state_transition :initialized => :take
17
36
  define_state_transition :take => :store
@@ -20,43 +39,57 @@ module Pione
20
39
  define_exception_handler Exception => :terminated
21
40
 
22
41
  # Sleeps till the logger clears logs.
42
+ #
23
43
  # @param [Float]
24
44
  # timespan for clearing logs
45
+ # @return [void]
25
46
  def wait_to_clear_logs(timespan=0.1)
26
- while count_tuple(Tuple[:log].any) > 0 || @logs.size > 0
47
+ while count_tuple(Tuple[:log].any) > 0 || @records.size > 0
27
48
  sleep timespan
28
49
  end
29
50
  end
30
51
 
52
+ def store_records
53
+ unless @records.empty?
54
+ @records.sort{|a,b| a.timestamp <=> b.timestamp}.each do |record|
55
+ @out.puts record.format
56
+ end
57
+ @out.flush
58
+ @out.fsync
59
+ @records = []
60
+ end
61
+ end
62
+
31
63
  private
32
64
 
33
- # Transits to the state +take_log+.
65
+ # Transits to the state +take+.
34
66
  def transit_to_take
35
67
  timeout(2) do
36
- @logs << take(Tuple[:log].any)
68
+ loop do
69
+ if @current_tuple = take(Tuple[:log].any)
70
+ @records << @current_tuple.message
71
+ @current_tuple = nil
72
+ end
73
+ end
37
74
  end
38
75
  rescue TimeoutError
39
- # ignore
76
+ if @current_tuple
77
+ @records << @current_tuple.message
78
+ @current_tuple = nil
79
+ end
40
80
  end
41
81
 
42
82
  # Transits to the state +store+.
43
83
  def transit_to_store
44
- unless @logs.empty?
45
- @logs.sort{|a,b| a.timestamp <=> b.timestamp}.each do |log|
46
- @out.puts log.message.format
47
- @out.flush
48
- @out.sync
49
- end
50
- @logs = []
51
- end
84
+ store_records
52
85
  end
53
86
 
54
87
  # State terminated.
55
88
  def transit_to_terminated
89
+ store_records
90
+ Util.ignore_exception {@out.close}
91
+ @temporary.copy(@location)
56
92
  super
57
- unless @out == STDOUT
58
- Util.ignore_exception { @out.close }
59
- end
60
93
  end
61
94
  end
62
95