use of com.hazelcast.jet.config.ProcessingGuarantee in project hazelcast by hazelcast.
the class JmsSourceBuilder method build.
/**
* Creates and returns the JMS {@link StreamSource} with the supplied
* components and the projection function {@code projectionFn}.
* <p>
* The given function must be stateless.
*
* @param projectionFn the function which creates output object from each
* message
* @param <T> the type of the items the source emits
*/
@Nonnull
public <T> StreamSource<T> build(@Nonnull FunctionEx<? super Message, ? extends T> projectionFn) {
String usernameLocal = username;
String passwordLocal = password;
String destinationLocal = destinationName;
ProcessingGuarantee maxGuaranteeLocal = maxGuarantee;
@SuppressWarnings("UnnecessaryLocalVariable") boolean isTopicLocal = isTopic;
if (connectionFn == null) {
connectionFn = factory -> requireNonNull(usernameLocal != null || passwordLocal != null ? factory.createConnection(usernameLocal, passwordLocal) : factory.createConnection());
}
if (consumerFn == null) {
checkNotNull(destinationLocal, "neither consumerFn nor destinationName set");
consumerFn = session -> session.createConsumer(isTopicLocal ? session.createTopic(destinationLocal) : session.createQueue(destinationLocal));
if (isTopic) {
// the user didn't specify a custom consumerFn and we know we're using a non-durable consumer
// for a topic - there's no point in using any guarantee, see `maxGuarantee`
maxGuaranteeLocal = ProcessingGuarantee.NONE;
}
}
ProcessingGuarantee maxGuaranteeFinal = maxGuaranteeLocal;
FunctionEx<? super ConnectionFactory, ? extends Connection> connectionFnLocal = connectionFn;
@SuppressWarnings("UnnecessaryLocalVariable") SupplierEx<? extends ConnectionFactory> factorySupplierLocal = factorySupplier;
SupplierEx<? extends Connection> newConnectionFn = () -> connectionFnLocal.apply(factorySupplierLocal.get());
FunctionEx<? super Session, ? extends MessageConsumer> consumerFnLocal = consumerFn;
boolean isSharedConsumerLocal = isSharedConsumer;
FunctionEx<? super Message, ?> messageIdFnLocal = messageIdFn;
FunctionEx<EventTimePolicy<? super T>, ProcessorMetaSupplier> metaSupplierFactory = policy -> isTopicLocal ? streamJmsTopicP(destinationLocal, isSharedConsumerLocal, maxGuaranteeFinal, policy, newConnectionFn, consumerFnLocal, messageIdFnLocal, projectionFn) : streamJmsQueueP(destinationLocal, maxGuaranteeFinal, policy, newConnectionFn, consumerFnLocal, messageIdFnLocal, projectionFn);
return Sources.streamFromProcessorWithWatermarks(sourceName(), true, metaSupplierFactory);
}
use of com.hazelcast.jet.config.ProcessingGuarantee in project hazelcast by hazelcast.
the class JmsSourceIntegrationTestBase method stressTest.
private void stressTest(boolean graceful, ProcessingGuarantee maxGuarantee, boolean useTopic) throws Exception {
lastListInStressTest = null;
final int MESSAGE_COUNT = 4_000;
Pipeline p = Pipeline.create();
String destName = "queue-" + counter++;
JmsSourceBuilder sourceBuilder;
if (useTopic) {
sourceBuilder = Sources.jmsTopicBuilder(getConnectionFactory()).sharedConsumer(true).consumerFn(s -> s.createSharedDurableConsumer(s.createTopic(destName), "foo-consumer"));
// create the durable subscriber now so that it doesn't lose the initial messages
try (Connection conn = getConnectionFactory().get().createConnection()) {
conn.setClientID("foo-client-id");
try (Session sess = conn.createSession(false, DUPS_OK_ACKNOWLEDGE)) {
sess.createDurableSubscriber(sess.createTopic(destName), "foo-consumer");
}
}
} else {
sourceBuilder = Sources.jmsQueueBuilder(getConnectionFactory()).destinationName(destName);
}
p.readFrom(sourceBuilder.maxGuarantee(maxGuarantee).build(msg -> Long.parseLong(((TextMessage) msg).getText()))).withoutTimestamps().peek().mapStateful(CopyOnWriteArrayList<Long>::new, (list, item) -> {
lastListInStressTest = list;
list.add(item);
return null;
}).writeTo(Sinks.logger());
Job job = instance().getJet().newJob(p, new JobConfig().setProcessingGuarantee(ProcessingGuarantee.EXACTLY_ONCE).setSnapshotIntervalMillis(50));
assertJobStatusEventually(job, RUNNING);
// start a producer that will produce MESSAGE_COUNT messages on the background to the queue, 1000 msgs/s
@SuppressWarnings("rawtypes") Future producerFuture = spawn(() -> {
try (Connection connection = getConnectionFactory().get().createConnection();
Session session = connection.createSession(false, AUTO_ACKNOWLEDGE);
MessageProducer producer = session.createProducer(useTopic ? session.createTopic(destName) : session.createQueue(destName))) {
long startTime = System.nanoTime();
for (int i = 0; i < MESSAGE_COUNT; i++) {
producer.send(session.createTextMessage(String.valueOf(i)));
Thread.sleep(Math.max(0, i - NANOSECONDS.toMillis(System.nanoTime() - startTime)));
}
} catch (Exception e) {
throw sneakyThrow(e);
}
});
int iteration = 0;
JobRepository jr = new JobRepository(instance());
waitForFirstSnapshot(jr, job.getId(), 20, true);
while (!producerFuture.isDone()) {
Thread.sleep(ThreadLocalRandom.current().nextInt(200));
// We also do it before the first restart to workaround https://issues.apache.org/jira/browse/ARTEMIS-2546
if (iteration++ % 3 == 0) {
waitForNextSnapshot(jr, job.getId(), 20, true);
}
((JobProxy) job).restart(graceful);
assertJobStatusEventually(job, RUNNING);
}
// call for the side-effect of throwing if the producer failed
producerFuture.get();
assertTrueEventually(() -> {
Map<Long, Long> counts = lastListInStressTest.stream().collect(Collectors.groupingBy(Function.identity(), TreeMap::new, Collectors.counting()));
for (long i = 0; i < MESSAGE_COUNT; i++) {
counts.putIfAbsent(i, 0L);
}
String countsStr = "counts: " + counts;
if (maxGuarantee == NONE) {
// we don't assert anything and only wait little more and check that the job didn't fail
sleepSeconds(1);
} else {
// in EXACTLY_ONCE the list must have each item exactly once
// in AT_LEAST_ONCE the list must have each item at least once
assertTrue(countsStr, counts.values().stream().allMatch(cnt -> maxGuarantee == EXACTLY_ONCE ? cnt == 1 : cnt > 0));
}
logger.info(countsStr);
}, 30);
assertEquals(job.getStatus(), RUNNING);
}
use of com.hazelcast.jet.config.ProcessingGuarantee in project hazelcast by hazelcast.
the class WriteFileP method init.
@Override
public void init(@Nonnull Outbox outbox, @Nonnull Context context) throws IOException {
this.context = context;
Files.createDirectories(directory);
ProcessingGuarantee guarantee = context.processingGuarantee() == EXACTLY_ONCE && !exactlyOnce ? AT_LEAST_ONCE : context.processingGuarantee();
utility = new UnboundedTransactionsProcessorUtility<>(outbox, context, guarantee, this::newFileName, this::newFileResource, this::recoverAndCommit, this::abortUnfinishedTransactions);
}
use of com.hazelcast.jet.config.ProcessingGuarantee in project hazelcast by hazelcast.
the class WriteKafkaP method init.
@Override
public void init(@Nonnull Outbox outbox, @Nonnull Context context) {
this.context = context;
ProcessingGuarantee guarantee = context.processingGuarantee() == EXACTLY_ONCE && !exactlyOnce ? AT_LEAST_ONCE : context.processingGuarantee();
snapshotUtility = new TransactionPoolSnapshotUtility<>(outbox, context, false, guarantee, TXN_POOL_SIZE, (processorIndex, txnIndex) -> new KafkaTransactionId(context.jobId(), context.jobConfig().getName(), context.vertexName(), processorIndex, txnIndex), txnId -> {
if (txnId != null) {
properties.put("transactional.id", txnId.getKafkaId());
}
return new KafkaTransaction<>(txnId, properties, context.logger());
}, txnId -> {
try {
recoverTransaction(txnId, true);
} catch (ProducerFencedException e) {
context.logger().warning("Failed to finish the commit of a transaction ID saved in the " + "snapshot, data loss can occur. Transaction id: " + txnId.getKafkaId(), e);
}
}, txnId -> recoverTransaction(txnId, false));
}
Aggregations