|
26 | 26 | import com.google.api.gax.rpc.NotFoundException; |
27 | 27 | import com.google.cloud.pubsub.v1.Publisher; |
28 | 28 | import com.google.common.cache.Cache; |
| 29 | +import com.google.common.collect.Lists; |
29 | 30 | import com.google.common.util.concurrent.MoreExecutors; |
30 | 31 | import com.google.inject.Inject; |
31 | 32 | import com.google.protobuf.ByteString; |
|
42 | 43 | import eu.toolchain.async.AsyncFramework; |
43 | 44 | import eu.toolchain.async.AsyncFuture; |
44 | 45 | import java.io.IOException; |
| 46 | +import java.util.ArrayList; |
45 | 47 | import java.util.Collection; |
46 | 48 | import java.util.Collections; |
47 | 49 | import java.util.List; |
|
58 | 60 | */ |
59 | 61 | public class PubsubPluginSink implements BatchablePluginSink { |
60 | 62 |
|
| 63 | + // Pubsub publish request limit is 10MB |
| 64 | + private final static double MAX_BATCH_SIZE_BYTES = 10_000_000.0; |
| 65 | + |
61 | 66 | private final Executor executorService = MoreExecutors.directExecutor(); |
62 | 67 | @Inject |
63 | 68 | AsyncFramework async; |
@@ -116,7 +121,18 @@ public AsyncFuture<Void> sendMetrics(Collection<Metric> metrics) { |
116 | 121 |
|
117 | 122 | try { |
118 | 123 | final ByteString m = ByteString.copyFrom(serializer.serialize(metrics, writeCache)); |
119 | | - publishPubSub(m); |
| 124 | + |
| 125 | + if (m.size() > MAX_BATCH_SIZE_BYTES) { |
| 126 | + logger.debug("Above byte limit, resizing batch"); |
| 127 | + int times = (int)Math.ceil(m.size()/MAX_BATCH_SIZE_BYTES); |
| 128 | + List<List<Metric>> collections = Lists.partition(new ArrayList<>(metrics), m.size()/times); |
| 129 | + for (List<Metric> l: collections) { |
| 130 | + final ByteString mResize = ByteString.copyFrom(serializer.serialize(l, writeCache)); |
| 131 | + publishPubSub(mResize); |
| 132 | + } |
| 133 | + } else { |
| 134 | + publishPubSub(m); |
| 135 | + } |
120 | 136 | } catch (Exception e) { |
121 | 137 | logger.error("Failed to serialize batch of metrics: ", e); |
122 | 138 | } |
|
0 commit comments