forked from docker-java/docker-java
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathResultCallbackTemplate.java
More file actions
145 lines (124 loc) · 4.19 KB
/
Copy pathResultCallbackTemplate.java
File metadata and controls
145 lines (124 loc) · 4.19 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
/*
* Created on 16.06.2015
*/
package com.github.dockerjava.api.async;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.Closeable;
import java.io.IOException;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
/**
* Abstract template implementation of {@link ResultCallback}
*
* @author Marcus Linke
*
*/
public abstract class ResultCallbackTemplate<RC_T extends ResultCallback<A_RES_T>, A_RES_T> implements
ResultCallback<A_RES_T> {
private static final Logger LOGGER = LoggerFactory.getLogger(ResultCallbackTemplate.class);
private final CountDownLatch started = new CountDownLatch(1);
private final CountDownLatch completed = new CountDownLatch(1);
private Closeable stream;
private boolean closed = false;
private Throwable firstError = null;
@Override
public void onStart(Closeable stream) {
this.stream = stream;
this.closed = false;
started.countDown();
}
@Override
public void onError(Throwable throwable) {
if (closed) return;
if (this.firstError == null) {
this.firstError = throwable;
}
try {
LOGGER.error("Error during callback", throwable);
} finally {
try {
close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
@Override
public void onComplete() {
try {
close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
@Override
public void close() throws IOException {
if (!closed) {
closed = true;
try {
if (stream != null) {
stream.close();
}
} finally {
completed.countDown();
}
}
}
/**
* Blocks until {@link ResultCallback#onComplete()} was called
*/
@SuppressWarnings("unchecked")
public RC_T awaitCompletion() throws InterruptedException {
completed.await();
// eventually (re)throws RuntimeException
throwFirstError();
return (RC_T) this;
}
/**
* Blocks until {@link ResultCallback#onComplete()} was called or the given timeout occurs
* @return {@code true} if completed and {@code false} if the waiting time elapsed
* before {@link ResultCallback#onComplete()} was called.
*/
public boolean awaitCompletion(long timeout, TimeUnit timeUnit) throws InterruptedException {
boolean result = completed.await(timeout, timeUnit);
throwFirstError();
return result;
}
/**
* Blocks until {@link ResultCallback#onStart(Closeable)} was called.
* {@link ResultCallback#onStart(Closeable)} is called when the request was processed on the server
* side and the response is incoming.
*/
@SuppressWarnings("unchecked")
public RC_T awaitStarted() throws InterruptedException {
started.await();
return (RC_T) this;
}
/**
* Blocks until {@link ResultCallback#onStart(Closeable)} was called or the given timeout occurs.
* {@link ResultCallback#onStart(Closeable)} is called when the request was processed on the server side
* and the response is incoming.
* @return {@code true} if started and {@code false} if the waiting time elapsed
* before {@link ResultCallback#onStart(Closeable)} was called.
*/
public boolean awaitStarted(long timeout, TimeUnit timeUnit) throws InterruptedException {
return started.await(timeout, timeUnit);
}
/**
* Throws the first occurred error as a runtime exception
* @throws com.github.dockerjava.api.exception.DockerException The first docker based Error
* @throws RuntimeException on any other occurred error
*/
protected void throwFirstError() {
if (firstError != null) {
if (firstError instanceof Error) {
throw (Error) firstError;
}
if (firstError instanceof RuntimeException) {
throw (RuntimeException) firstError;
}
throw new RuntimeException(firstError);
}
}
}