embulk 0.5.5 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (33) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +2 -2
  3. data/build.gradle +1 -1
  4. data/embulk-core/src/main/java/org/embulk/command/Runner.java +7 -7
  5. data/embulk-core/src/main/java/org/embulk/exec/BulkLoader.java +664 -0
  6. data/embulk-core/src/main/java/org/embulk/exec/ExecModule.java +5 -0
  7. data/embulk-core/src/main/java/org/embulk/exec/LocalExecutorPlugin.java +130 -0
  8. data/embulk-core/src/main/java/org/embulk/exec/LocalThreadExecutor.java +34 -0
  9. data/embulk-core/src/main/java/org/embulk/exec/PooledBufferAllocator.java +3 -3
  10. data/embulk-core/src/main/java/org/embulk/exec/PreviewExecutor.java +1 -1
  11. data/embulk-core/src/main/java/org/embulk/exec/ResumeState.java +7 -6
  12. data/embulk-core/src/main/java/org/embulk/jruby/JRubyPluginSource.java +3 -0
  13. data/embulk-core/src/main/java/org/embulk/spi/Buffer.java +35 -3
  14. data/embulk-core/src/main/java/org/embulk/spi/Exec.java +4 -1
  15. data/embulk-core/src/main/java/org/embulk/spi/ExecAction.java +1 -1
  16. data/embulk-core/src/main/java/org/embulk/spi/ExecutorPlugin.java +19 -0
  17. data/embulk-core/src/main/java/org/embulk/spi/Page.java +6 -0
  18. data/embulk-core/src/main/java/org/embulk/spi/PluginClassLoader.java +73 -1
  19. data/embulk-core/src/main/java/org/embulk/spi/ProcessState.java +10 -0
  20. data/embulk-core/src/main/java/org/embulk/spi/ProcessTask.java +118 -0
  21. data/embulk-core/src/main/java/org/embulk/spi/TaskState.java +70 -0
  22. data/embulk-core/src/main/java/org/embulk/spi/util/Executors.java +92 -0
  23. data/embulk-core/src/main/java/org/embulk/spi/util/Filters.java +17 -3
  24. data/embulk-core/src/test/java/org/embulk/spi/TestBuffer.java +24 -0
  25. data/embulk-docs/src/recipe/scheduled-csv-load-to-elasticsearch-kibana4.rst +1 -1
  26. data/embulk-docs/src/release.rst +1 -0
  27. data/embulk-docs/src/release/release-0.6.0.rst +34 -0
  28. data/lib/embulk/executor_plugin.rb +23 -0
  29. data/lib/embulk/java_plugin.rb +5 -0
  30. data/lib/embulk/plugin.rb +13 -2
  31. data/lib/embulk/version.rb +1 -1
  32. metadata +15 -5
  33. data/embulk-core/src/main/java/org/embulk/exec/LocalExecutor.java +0 -660
@@ -1,3 +1,3 @@
1
1
  module Embulk
2
- VERSION = '0.5.5'
2
+ VERSION = '0.6.0'
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: embulk
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.5
4
+ version: 0.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sadayuki Furuhashi
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-04-07 00:00:00.000000000 Z
11
+ date: 2015-04-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -125,6 +125,7 @@ files:
125
125
  - embulk-core/src/main/java/org/embulk/config/TaskSource.java
126
126
  - embulk-core/src/main/java/org/embulk/config/TaskValidationException.java
127
127
  - embulk-core/src/main/java/org/embulk/config/TaskValidator.java
128
+ - embulk-core/src/main/java/org/embulk/exec/BulkLoader.java
128
129
  - embulk-core/src/main/java/org/embulk/exec/ExecModule.java
129
130
  - embulk-core/src/main/java/org/embulk/exec/ExecutionInterruptedException.java
130
131
  - embulk-core/src/main/java/org/embulk/exec/ExecutionResult.java
@@ -132,7 +133,8 @@ files:
132
133
  - embulk-core/src/main/java/org/embulk/exec/ForGuess.java
133
134
  - embulk-core/src/main/java/org/embulk/exec/ForSystemConfig.java
134
135
  - embulk-core/src/main/java/org/embulk/exec/GuessExecutor.java
135
- - embulk-core/src/main/java/org/embulk/exec/LocalExecutor.java
136
+ - embulk-core/src/main/java/org/embulk/exec/LocalExecutorPlugin.java
137
+ - embulk-core/src/main/java/org/embulk/exec/LocalThreadExecutor.java
136
138
  - embulk-core/src/main/java/org/embulk/exec/LoggerProvider.java
137
139
  - embulk-core/src/main/java/org/embulk/exec/NoSampleException.java
138
140
  - embulk-core/src/main/java/org/embulk/exec/PartialExecutionException.java
@@ -162,6 +164,7 @@ files:
162
164
  - embulk-core/src/main/java/org/embulk/spi/Exec.java
163
165
  - embulk-core/src/main/java/org/embulk/spi/ExecAction.java
164
166
  - embulk-core/src/main/java/org/embulk/spi/ExecSession.java
167
+ - embulk-core/src/main/java/org/embulk/spi/ExecutorPlugin.java
165
168
  - embulk-core/src/main/java/org/embulk/spi/Extension.java
166
169
  - embulk-core/src/main/java/org/embulk/spi/FileInput.java
167
170
  - embulk-core/src/main/java/org/embulk/spi/FileInputPlugin.java
@@ -181,8 +184,11 @@ files:
181
184
  - embulk-core/src/main/java/org/embulk/spi/PageReader.java
182
185
  - embulk-core/src/main/java/org/embulk/spi/ParserPlugin.java
183
186
  - embulk-core/src/main/java/org/embulk/spi/PluginClassLoader.java
187
+ - embulk-core/src/main/java/org/embulk/spi/ProcessState.java
188
+ - embulk-core/src/main/java/org/embulk/spi/ProcessTask.java
184
189
  - embulk-core/src/main/java/org/embulk/spi/Schema.java
185
190
  - embulk-core/src/main/java/org/embulk/spi/SchemaConfig.java
191
+ - embulk-core/src/main/java/org/embulk/spi/TaskState.java
186
192
  - embulk-core/src/main/java/org/embulk/spi/Transactional.java
187
193
  - embulk-core/src/main/java/org/embulk/spi/TransactionalFileInput.java
188
194
  - embulk-core/src/main/java/org/embulk/spi/TransactionalFileOutput.java
@@ -208,6 +214,7 @@ files:
208
214
  - embulk-core/src/main/java/org/embulk/spi/util/CharsetSerDe.java
209
215
  - embulk-core/src/main/java/org/embulk/spi/util/Decoders.java
210
216
  - embulk-core/src/main/java/org/embulk/spi/util/Encoders.java
217
+ - embulk-core/src/main/java/org/embulk/spi/util/Executors.java
211
218
  - embulk-core/src/main/java/org/embulk/spi/util/FileInputInputStream.java
212
219
  - embulk-core/src/main/java/org/embulk/spi/util/FileOutputOutputStream.java
213
220
  - embulk-core/src/main/java/org/embulk/spi/util/Filters.java
@@ -233,6 +240,7 @@ files:
233
240
  - embulk-core/src/test/java/org/embulk/spi/MockFormatterPlugin.java
234
241
  - embulk-core/src/test/java/org/embulk/spi/MockParserPlugin.java
235
242
  - embulk-core/src/test/java/org/embulk/spi/PageTestUtils.java
243
+ - embulk-core/src/test/java/org/embulk/spi/TestBuffer.java
236
244
  - embulk-core/src/test/java/org/embulk/spi/TestFileInputInputStream.java
237
245
  - embulk-core/src/test/java/org/embulk/spi/TestFileInputRunner.java
238
246
  - embulk-core/src/test/java/org/embulk/spi/TestFileOutputRunner.java
@@ -280,6 +288,7 @@ files:
280
288
  - embulk-docs/src/release/release-0.5.3.rst
281
289
  - embulk-docs/src/release/release-0.5.4.rst
282
290
  - embulk-docs/src/release/release-0.5.5.rst
291
+ - embulk-docs/src/release/release-0.6.0.rst
283
292
  - embulk-standards/build.gradle
284
293
  - embulk-standards/src/main/java/org/embulk/standards/CsvFormatterPlugin.java
285
294
  - embulk-standards/src/main/java/org/embulk/standards/CsvParserPlugin.java
@@ -348,6 +357,7 @@ files:
348
357
  - lib/embulk/decoder_plugin.rb
349
358
  - lib/embulk/encoder_plugin.rb
350
359
  - lib/embulk/error.rb
360
+ - lib/embulk/executor_plugin.rb
351
361
  - lib/embulk/file_input.rb
352
362
  - lib/embulk/file_input_plugin.rb
353
363
  - lib/embulk/file_output.rb
@@ -384,8 +394,8 @@ files:
384
394
  - classpath/bval-jsr303-0.5.jar
385
395
  - classpath/commons-beanutils-core-1.8.3.jar
386
396
  - classpath/commons-lang3-3.1.jar
387
- - classpath/embulk-core-0.5.5.jar
388
- - classpath/embulk-standards-0.5.5.jar
397
+ - classpath/embulk-core-0.6.0.jar
398
+ - classpath/embulk-standards-0.6.0.jar
389
399
  - classpath/guava-18.0.jar
390
400
  - classpath/guice-3.0.jar
391
401
  - classpath/guice-multibindings-3.0.jar
@@ -1,660 +0,0 @@
1
- package org.embulk.exec;
2
-
3
- import java.util.List;
4
- import java.util.Arrays;
5
- import java.util.ArrayList;
6
- import java.util.concurrent.Callable;
7
- import java.util.concurrent.Future;
8
- import java.util.concurrent.Executors;
9
- import java.util.concurrent.ExecutorService;
10
- import java.util.concurrent.ExecutionException;
11
- import java.util.concurrent.atomic.AtomicInteger;
12
-
13
- import com.google.common.collect.ImmutableList;
14
- import com.google.inject.Inject;
15
- import com.google.inject.Injector;
16
- import com.google.common.base.Throwables;
17
- import com.google.common.base.Predicates;
18
- import com.google.common.collect.Iterables;
19
- import com.google.common.util.concurrent.ThreadFactoryBuilder;
20
- import org.embulk.config.Task;
21
- import org.embulk.config.Config;
22
- import org.embulk.config.ConfigDefault;
23
- import org.embulk.config.ConfigSource;
24
- import org.embulk.config.TaskSource;
25
- import org.embulk.config.ConfigDiff;
26
- import org.embulk.config.CommitReport;
27
- import org.embulk.plugin.PluginType;
28
- import org.embulk.spi.Schema;
29
- import org.embulk.spi.Exec;
30
- import org.embulk.spi.ExecSession;
31
- import org.embulk.spi.ExecAction;
32
- import org.embulk.spi.InputPlugin;
33
- import org.embulk.spi.FilterPlugin;
34
- import org.embulk.spi.OutputPlugin;
35
- import org.embulk.spi.PageOutput;
36
- import org.embulk.spi.TransactionalPageOutput;
37
- import org.embulk.spi.util.Filters;
38
- import org.slf4j.Logger;
39
-
40
- public class LocalExecutor
41
- {
42
- private final Injector injector;
43
- private final ConfigSource systemConfig;
44
- private final int maxThreads;
45
- private final ExecutorService executor;
46
-
47
- public interface ExecutorTask
48
- extends Task
49
- {
50
- @Config("in")
51
- public ConfigSource getInputConfig();
52
-
53
- @Config("filters")
54
- @ConfigDefault("[]")
55
- public List<ConfigSource> getFilterConfigs();
56
-
57
- @Config("out")
58
- public ConfigSource getOutputConfig();
59
-
60
- public TaskSource getInputTask();
61
- public void setInputTask(TaskSource taskSource);
62
-
63
- public List<TaskSource> getFilterTasks();
64
- public void setFilterTasks(List<TaskSource> taskSources);
65
-
66
- public TaskSource getOutputTask();
67
- public void setOutputTask(TaskSource taskSource);
68
- }
69
-
70
- @Inject
71
- public LocalExecutor(Injector injector,
72
- @ForSystemConfig ConfigSource systemConfig)
73
- {
74
- this.injector = injector;
75
- this.systemConfig = systemConfig;
76
-
77
- int defaultMaxThreads = Runtime.getRuntime().availableProcessors() * 2;
78
- this.maxThreads = systemConfig.get(Integer.class, "max_threads", defaultMaxThreads);
79
- this.executor = Executors.newFixedThreadPool(maxThreads,
80
- new ThreadFactoryBuilder()
81
- .setNameFormat("embulk-executor-%d")
82
- .setDaemon(true)
83
- .build());
84
- }
85
-
86
- private static class ProcessState
87
- {
88
- private final Logger logger;
89
- private volatile boolean[] started;
90
- private volatile boolean[] finished;
91
- private volatile Schema inputSchema;
92
- private volatile Schema outputSchema;
93
- private volatile Throwable[] exceptions;
94
- private volatile CommitReport[] inputCommitReports;
95
- private volatile CommitReport[] outputCommitReports;
96
- private volatile ConfigDiff inputConfigDiff;
97
- private volatile ConfigDiff outputConfigDiff;
98
- private int taskCount;
99
-
100
- public ProcessState(Logger logger)
101
- {
102
- this.logger = logger;
103
- }
104
-
105
- public Logger getLogger()
106
- {
107
- return logger;
108
- }
109
-
110
- public void initialize(int count)
111
- {
112
- this.started = new boolean[count];
113
- this.finished = new boolean[count];
114
- this.exceptions = new Throwable[count];
115
- this.inputCommitReports = new CommitReport[count];
116
- this.outputCommitReports = new CommitReport[count];
117
- this.taskCount = count;
118
- }
119
-
120
- public void setInputSchema(Schema inputSchema)
121
- {
122
- this.inputSchema = inputSchema;
123
- }
124
-
125
- public void setOutputSchema(Schema outputSchema)
126
- {
127
- this.outputSchema = outputSchema;
128
- }
129
-
130
- public Schema getInputSchema()
131
- {
132
- return inputSchema;
133
- }
134
-
135
- public Schema getOutputSchema()
136
- {
137
- return outputSchema;
138
- }
139
-
140
- public boolean isAnyStarted()
141
- {
142
- if (started == null) {
143
- return false;
144
- }
145
- for (boolean b : started) {
146
- if (b) { return true; }
147
- }
148
- return false;
149
- }
150
-
151
- public void start(int i)
152
- {
153
- started[i] = true;
154
- }
155
-
156
- public void finish(int i)
157
- {
158
- finished[i] = true;
159
- }
160
-
161
- public int getTaskCount()
162
- {
163
- return taskCount;
164
- }
165
-
166
- public int getStartedCount()
167
- {
168
- int count = 0;
169
- for (int i=0; i < started.length; i++) {
170
- if (started[i]) { count++; }
171
- }
172
- return count;
173
- }
174
-
175
- public int getFinishedCount()
176
- {
177
- int count = 0;
178
- for (int i=0; i < finished.length; i++) {
179
- if (finished[i]) { count++; }
180
- }
181
- return count;
182
- }
183
-
184
- public void setInputCommitReport(int i, CommitReport inputCommitReport)
185
- {
186
- if (inputCommitReport == null) {
187
- inputCommitReport = Exec.newCommitReport();
188
- }
189
- this.inputCommitReports[i] = inputCommitReport;
190
- }
191
-
192
- public void setOutputCommitReport(int i, CommitReport outputCommitReport)
193
- {
194
- if (outputCommitReport == null) {
195
- outputCommitReport = Exec.newCommitReport();
196
- }
197
- this.outputCommitReports[i] = outputCommitReport;
198
- }
199
-
200
- public boolean isOutputCommitted(int i)
201
- {
202
- return outputCommitReports[i] != null;
203
- }
204
-
205
- public void setException(int i, Throwable exception)
206
- {
207
- this.exceptions[i] = exception;
208
- }
209
-
210
- public boolean isAllCommitted()
211
- {
212
- if (taskCount <= 0) {
213
- // not initialized
214
- return false;
215
- }
216
- for (int i=0; i < taskCount; i++) {
217
- if (!isOutputCommitted(i)) {
218
- return false;
219
- }
220
- }
221
- return true;
222
- }
223
-
224
- public boolean isAnyCommitted()
225
- {
226
- for (int i=0; i < taskCount; i++) {
227
- if (isOutputCommitted(i)) {
228
- return true;
229
- }
230
- }
231
- return false;
232
- }
233
-
234
- public void setOutputConfigDiff(ConfigDiff outputConfigDiff)
235
- {
236
- if (outputConfigDiff == null) {
237
- outputConfigDiff = Exec.newConfigDiff();
238
- }
239
- this.outputConfigDiff = outputConfigDiff;
240
- }
241
-
242
- public void setInputConfigDiff(ConfigDiff inputConfigDiff)
243
- {
244
- if (inputConfigDiff == null) {
245
- inputConfigDiff = Exec.newConfigDiff();
246
- }
247
- this.inputConfigDiff = inputConfigDiff;
248
- }
249
-
250
- public List<CommitReport> getInputCommitReports()
251
- {
252
- return ImmutableList.copyOf(inputCommitReports);
253
- }
254
-
255
- public List<CommitReport> getOutputCommitReports()
256
- {
257
- return ImmutableList.copyOf(outputCommitReports);
258
- }
259
-
260
- public RuntimeException getRepresentativeException()
261
- {
262
- RuntimeException top = null;
263
- for (Throwable ex : exceptions) {
264
- if (ex != null) {
265
- if (top != null) {
266
- top.addSuppressed(ex);
267
- } else {
268
- if (ex instanceof RuntimeException) {
269
- top = (RuntimeException) ex;
270
- } else {
271
- top = new RuntimeException(ex);
272
- }
273
- }
274
- }
275
- }
276
- if (top == null) {
277
- top = new RuntimeException("Some transactions are not committed");
278
- }
279
- return top;
280
- }
281
-
282
- public int getCommittedUnclosedCount()
283
- {
284
- int count = 0;
285
- for (int i=0; i < exceptions.length; i++) {
286
- if (exceptions[i] != null && isOutputCommitted(i)) {
287
- count++;
288
- }
289
- }
290
- return count;
291
- }
292
-
293
- public ExecutionResult buildExecuteResult()
294
- {
295
- return buildExecuteResultWithWarningException(null);
296
- }
297
-
298
- public ExecutionResult buildExecuteResultWithWarningException(Throwable ex)
299
- {
300
- ConfigDiff configDiff = Exec.newConfigDiff();
301
- if (inputConfigDiff != null) {
302
- configDiff.getNestedOrSetEmpty("in").merge(inputConfigDiff);
303
- }
304
- if (outputConfigDiff != null) {
305
- configDiff.getNestedOrSetEmpty("out").merge(outputConfigDiff);
306
- }
307
-
308
- ImmutableList.Builder<Throwable> ignoredExceptions = ImmutableList.builder();
309
- for (Throwable e : exceptions) {
310
- if (e != null) {
311
- ignoredExceptions.add(e);
312
- }
313
- }
314
- if (ex != null) {
315
- ignoredExceptions.add(ex);
316
- }
317
-
318
- return new ExecutionResult(configDiff, ignoredExceptions.build());
319
- }
320
-
321
- public ResumeState buildResumeState(ExecutorTask task, ExecSession exec)
322
- {
323
- return new ResumeState(
324
- exec.getSessionConfigSource(),
325
- task.getInputTask(), task.getOutputTask(),
326
- inputSchema, outputSchema,
327
- Arrays.asList(inputCommitReports), Arrays.asList(outputCommitReports));
328
- }
329
-
330
- public PartialExecutionException buildPartialExecuteException(Throwable cause,
331
- ExecutorTask task, ExecSession exec)
332
- {
333
- return new PartialExecutionException(cause, buildResumeState(task, exec));
334
- }
335
- }
336
-
337
- protected InputPlugin newInputPlugin(ExecutorTask task)
338
- {
339
- return Exec.newPlugin(InputPlugin.class, task.getInputConfig().get(PluginType.class, "type"));
340
- }
341
-
342
- protected List<FilterPlugin> newFilterPlugins(ExecutorTask task)
343
- {
344
- return Filters.newFilterPlugins(Exec.session(), task.getFilterConfigs());
345
- }
346
-
347
- protected OutputPlugin newOutputPlugin(ExecutorTask task)
348
- {
349
- return Exec.newPlugin(OutputPlugin.class, task.getOutputConfig().get(PluginType.class, "type"));
350
- }
351
-
352
- public ExecutionResult run(ExecSession exec, final ConfigSource config)
353
- {
354
- try {
355
- return Exec.doWith(exec, new ExecAction<ExecutionResult>() {
356
- public ExecutionResult run()
357
- {
358
- try (SetCurrentThreadName dontCare = new SetCurrentThreadName("transaction")) {
359
- return doRun(config);
360
- }
361
- }
362
- });
363
- } catch (Exception ex) {
364
- throw Throwables.propagate(ex);
365
- }
366
- }
367
-
368
- public ExecutionResult resume(final ConfigSource config, final ResumeState resume)
369
- {
370
- try {
371
- ExecSession exec = new ExecSession(injector, resume.getExecSessionConfigSource());
372
- return Exec.doWith(exec, new ExecAction<ExecutionResult>() {
373
- public ExecutionResult run()
374
- {
375
- try (SetCurrentThreadName dontCare = new SetCurrentThreadName("resume")) {
376
- return doResume(config, resume);
377
- }
378
- }
379
- });
380
- } catch (Exception ex) {
381
- throw Throwables.propagate(ex);
382
- }
383
- }
384
-
385
- public void cleanup(final ConfigSource config, final ResumeState resume)
386
- {
387
- try {
388
- ExecSession exec = new ExecSession(injector, resume.getExecSessionConfigSource());
389
- Exec.doWith(exec, new ExecAction<Void>() {
390
- public Void run()
391
- {
392
- try (SetCurrentThreadName dontCare = new SetCurrentThreadName("cleanup")) {
393
- doCleanup(config, resume);
394
- return null;
395
- }
396
- }
397
- });
398
- } catch (Exception ex) {
399
- throw Throwables.propagate(ex);
400
- }
401
- }
402
-
403
- public void doCleanup(ConfigSource config, ResumeState resume)
404
- {
405
- ExecutorTask task = config.loadConfig(ExecutorTask.class);
406
- InputPlugin in = newInputPlugin(task);
407
- OutputPlugin out = newOutputPlugin(task);
408
-
409
- List<CommitReport> successInputCommitReports = ImmutableList.copyOf(
410
- Iterables.filter(resume.getInputCommitReports(), Predicates.notNull()));
411
- List<CommitReport> successOutputCommitReports = ImmutableList.copyOf(
412
- Iterables.filter(resume.getOutputCommitReports(), Predicates.notNull()));
413
-
414
- in.cleanup(resume.getInputTaskSource(), resume.getInputSchema(),
415
- resume.getInputCommitReports().size(), successInputCommitReports);
416
-
417
- out.cleanup(resume.getOutputTaskSource(), resume.getOutputSchema(),
418
- resume.getOutputCommitReports().size(), successOutputCommitReports);
419
- }
420
-
421
- private ExecutionResult doRun(ConfigSource config)
422
- {
423
- final ExecutorTask task = config.loadConfig(ExecutorTask.class);
424
-
425
- final InputPlugin in = newInputPlugin(task);
426
- final List<FilterPlugin> filterPlugins = newFilterPlugins(task);
427
- final OutputPlugin out = newOutputPlugin(task);
428
-
429
- final ProcessState state = new ProcessState(Exec.getLogger(LocalExecutor.class));
430
- try {
431
- ConfigDiff inputConfigDiff = in.transaction(task.getInputConfig(), new InputPlugin.Control() {
432
- public List<CommitReport> run(final TaskSource inputTask, final Schema inputSchema, final int taskCount)
433
- {
434
- state.initialize(taskCount);
435
- state.setInputSchema(inputSchema);
436
- Filters.transaction(filterPlugins, task.getFilterConfigs(), inputSchema, new Filters.Control() {
437
- public void run(final List<TaskSource> filterTasks, final List<Schema> filterSchemas)
438
- {
439
- Schema outputSchema = last(filterSchemas);
440
- state.setOutputSchema(outputSchema);
441
- ConfigDiff outputConfigDiff = out.transaction(task.getOutputConfig(), outputSchema, taskCount, new OutputPlugin.Control() {
442
- public List<CommitReport> run(final TaskSource outputTask)
443
- {
444
- task.setInputTask(inputTask);
445
- task.setFilterTasks(filterTasks);
446
- task.setOutputTask(outputTask);
447
-
448
- if (taskCount > 0) {
449
- process(task.dump(), filterSchemas, taskCount, state);
450
- if (!state.isAllCommitted()) {
451
- throw state.getRepresentativeException();
452
- }
453
- } else {
454
- // TODO warning?
455
- }
456
- return state.getOutputCommitReports();
457
- }
458
- });
459
- state.setOutputConfigDiff(outputConfigDiff);
460
- }
461
- });
462
- return state.getInputCommitReports();
463
- }
464
- });
465
- state.setInputConfigDiff(inputConfigDiff);
466
-
467
- try {
468
- doCleanup(config, state.buildResumeState(task, Exec.session()));
469
- } catch (Exception ex) {
470
- state.logger.warn("Commit succeeded but cleanup failed. Ignoring this exception.", ex); // TODO
471
- }
472
-
473
- return state.buildExecuteResult();
474
-
475
- } catch (Throwable ex) {
476
- if (state.isAllCommitted()) {
477
- // ignore the exception
478
- return state.buildExecuteResultWithWarningException(ex);
479
- }
480
- if (!state.isAnyStarted()) {
481
- throw ex;
482
- }
483
- throw state.buildPartialExecuteException(ex, task, Exec.session());
484
- }
485
- }
486
-
487
- private ExecutionResult doResume(ConfigSource config, final ResumeState resume)
488
- {
489
- final ExecutorTask task = config.loadConfig(ExecutorTask.class);
490
-
491
- final InputPlugin in = newInputPlugin(task);
492
- final List<FilterPlugin> filterPlugins = newFilterPlugins(task);
493
- final OutputPlugin out = newOutputPlugin(task);
494
-
495
- final ProcessState state = new ProcessState(Exec.getLogger(LocalExecutor.class));
496
- try {
497
- ConfigDiff inputConfigDiff = in.resume(resume.getInputTaskSource(), resume.getInputSchema(), resume.getInputCommitReports().size(), new InputPlugin.Control() {
498
- public List<CommitReport> run(final TaskSource inputTask, final Schema inputSchema, final int taskCount)
499
- {
500
- // TODO validate inputTask?
501
- // TODO validate inputSchema
502
- // TODO validate taskCount
503
- state.initialize(taskCount);
504
- Filters.transaction(filterPlugins, task.getFilterConfigs(), inputSchema, new Filters.Control() {
505
- public void run(final List<TaskSource> filterTasks, final List<Schema> filterSchemas)
506
- {
507
- Schema outputSchema = last(filterSchemas);
508
- state.setOutputSchema(outputSchema);
509
- ConfigDiff outputConfigDiff = out.resume(resume.getOutputTaskSource(), outputSchema, taskCount, new OutputPlugin.Control() {
510
- public List<CommitReport> run(final TaskSource outputTask)
511
- {
512
- // TODO validate outputTask?
513
- task.setInputTask(inputTask);
514
- task.setFilterTasks(filterTasks);
515
- task.setOutputTask(outputTask);
516
-
517
- for (int i=0; i < resume.getOutputCommitReports().size(); i++) {
518
- if (resume.getOutputCommitReports().get(i) != null) {
519
- state.start(i);
520
- state.setInputCommitReport(i, resume.getInputCommitReports().get(i));
521
- state.setOutputCommitReport(i, resume.getOutputCommitReports().get(i));
522
- state.finish(i);
523
- }
524
- }
525
-
526
- if (taskCount > 0) {
527
- process(task.dump(), filterSchemas, taskCount, state);
528
- if (!state.isAllCommitted()) {
529
- throw state.getRepresentativeException();
530
- }
531
- } else {
532
- // TODO warning?
533
- }
534
- return state.getOutputCommitReports();
535
- }
536
- });
537
- state.setOutputConfigDiff(outputConfigDiff);
538
- }
539
- });
540
- return state.getInputCommitReports();
541
- }
542
- });
543
- state.setInputConfigDiff(inputConfigDiff);
544
-
545
- try {
546
- doCleanup(config, state.buildResumeState(task, Exec.session()));
547
- } catch (Exception ex) {
548
- state.logger.warn("Commit succeeded but cleanup failed. Ignoring this exception.", ex); // TODO
549
- }
550
-
551
- return state.buildExecuteResult();
552
-
553
- } catch (Throwable ex) {
554
- if (state.isAllCommitted()) {
555
- // ignore the exception
556
- return state.buildExecuteResultWithWarningException(ex);
557
- }
558
- if (!state.isAnyStarted()) {
559
- throw ex;
560
- }
561
- throw state.buildPartialExecuteException(ex, task, Exec.session());
562
- }
563
- }
564
-
565
- private void process(TaskSource taskSource, List<Schema> filterSchemas, int taskCount,
566
- ProcessState state)
567
- {
568
- List<Future<Throwable>> futures = new ArrayList<>(taskCount);
569
- try {
570
- for (int i=0; i < taskCount; i++) {
571
- if (state.isOutputCommitted(i)) {
572
- state.getLogger().warn("Skipped resumed task {}", i);
573
- futures.add(null); // resumed
574
- } else {
575
- futures.add(startProcessor(taskSource, filterSchemas, i, state));
576
- }
577
- }
578
- showProgress(state);
579
-
580
- for (int i=0; i < taskCount; i++) {
581
- if (futures.get(i) == null) {
582
- continue;
583
- }
584
- try {
585
- state.setException(i, futures.get(i).get());
586
- } catch (ExecutionException ex) {
587
- state.setException(i, ex.getCause());
588
- //Throwables.propagate(ex.getCause());
589
- } catch (InterruptedException ex) {
590
- state.setException(i, new ExecutionInterruptedException(ex));
591
- }
592
- showProgress(state);
593
- }
594
- } finally {
595
- for (Future<Throwable> future : futures) {
596
- if (future != null && !future.isDone()) {
597
- future.cancel(true);
598
- // TODO join?
599
- }
600
- }
601
- }
602
- }
603
-
604
- private void showProgress(ProcessState state)
605
- {
606
- int total = state.getTaskCount();
607
- int finished = state.getFinishedCount();
608
- int started = state.getStartedCount();
609
- state.getLogger().info(String.format("{done:%3d / %d, running: %d}", finished, total, started - finished));
610
- }
611
-
612
- private Future<Throwable> startProcessor(final TaskSource taskSource,
613
- final List<Schema> filterSchemas, final int index,
614
- final ProcessState state)
615
- {
616
- return executor.submit(new Callable<Throwable>() {
617
- public Throwable call()
618
- {
619
- try (SetCurrentThreadName dontCare = new SetCurrentThreadName(String.format("task-%04d", index))) {
620
- final ExecutorTask task = taskSource.loadTask(ExecutorTask.class);
621
- final InputPlugin in = newInputPlugin(task);
622
- final List<FilterPlugin> filterPlugins = newFilterPlugins(task);
623
- final OutputPlugin out = newOutputPlugin(task);
624
-
625
- TransactionalPageOutput tran = out.open(task.getOutputTask(), last(filterSchemas), index);
626
- PageOutput closeThis = tran;
627
- state.start(index);
628
- try {
629
- PageOutput filtered = closeThis = Filters.open(filterPlugins, task.getFilterTasks(), filterSchemas, tran);
630
- state.setInputCommitReport(index, in.run(task.getInputTask(), first(filterSchemas), index, filtered));
631
- state.setOutputCommitReport(index, tran.commit()); // TODO check output.finish() is called. wrap or abstract
632
- return null;
633
- } finally {
634
- try {
635
- try {
636
- if (!state.isOutputCommitted(index)) {
637
- tran.abort();
638
- }
639
- } finally {
640
- closeThis.close();
641
- }
642
- } finally {
643
- state.finish(index);
644
- }
645
- }
646
- }
647
- }
648
- });
649
- }
650
-
651
- private static Schema first(List<Schema> filterSchemas)
652
- {
653
- return filterSchemas.get(0);
654
- }
655
-
656
- private static Schema last(List<Schema> filterSchemas)
657
- {
658
- return filterSchemas.get(filterSchemas.size() - 1);
659
- }
660
- }