use of io.camunda.zeebe.protocol.impl.record.value.job.JobRecord in project zeebe by camunda.
the class JobBatchCollector method collectJobs.
/**
* Collects jobs to be added to the given {@code record}. The jobs and their keys are added
* directly to the given record.
*
* <p>This method will fail only if it could not activate anything because the batch would be too
* large, but there was at least one job to activate. On failure, it will return that job and its
* key. On success, it will return the amount of jobs activated.
*
* @param record the batch activate command; jobs and their keys will be added directly into it
* @return the amount of activated jobs on success, or a job which was too large to activate
*/
Either<TooLargeJob, Integer> collectJobs(final TypedRecord<JobBatchRecord> record) {
final JobBatchRecord value = record.getValue();
final ValueArray<JobRecord> jobIterator = value.jobs();
final ValueArray<LongValue> jobKeyIterator = value.jobKeys();
final Collection<DirectBuffer> requestedVariables = collectVariableNames(value);
final var maxActivatedCount = value.getMaxJobsToActivate();
final var activatedCount = new MutableInteger(0);
final var jobCopyBuffer = new ExpandableArrayBuffer();
final var unwritableJob = new MutableReference<TooLargeJob>();
jobState.forEachActivatableJobs(value.getTypeBuffer(), (key, jobRecord) -> {
// fill in the job record properties first in order to accurately estimate its size before
// adding it to the batch
final var deadline = record.getTimestamp() + value.getTimeout();
jobRecord.setDeadline(deadline).setWorker(value.getWorkerBuffer());
setJobVariables(requestedVariables, jobRecord, jobRecord.getElementInstanceKey());
// the expected length is based on the current record's length plus the length of the job
// record we would add to the batch, the number of bytes taken by the additional job key,
// as well as one byte required per job key for its type header. if we ever add more, this
// should be updated accordingly.
final var jobRecordLength = jobRecord.getLength();
final var expectedEventLength = record.getLength() + jobRecordLength + Long.BYTES + 1;
if (activatedCount.value <= maxActivatedCount && canWriteEventOfLength.test(expectedEventLength)) {
appendJobToBatch(jobIterator, jobKeyIterator, jobCopyBuffer, key, jobRecord);
activatedCount.increment();
} else {
// activate it
if (activatedCount.value == 0) {
unwritableJob.set(new TooLargeJob(key, jobRecord));
}
value.setTruncated(true);
return false;
}
return activatedCount.value < maxActivatedCount;
});
if (unwritableJob.ref != null) {
return Either.left(unwritableJob.ref);
}
return Either.right(activatedCount.value);
}
use of io.camunda.zeebe.protocol.impl.record.value.job.JobRecord in project zeebe by camunda.
the class JobBatchCollector method appendJobToBatch.
private void appendJobToBatch(final ValueArray<JobRecord> jobIterator, final ValueArray<LongValue> jobKeyIterator, final ExpandableArrayBuffer jobCopyBuffer, final Long key, final JobRecord jobRecord) {
jobKeyIterator.add().setValue(key);
final JobRecord arrayValueJob = jobIterator.add();
// clone job record since buffer is reused during iteration
jobRecord.write(jobCopyBuffer, 0);
arrayValueJob.wrap(jobCopyBuffer, 0, jobRecord.getLength());
}
use of io.camunda.zeebe.protocol.impl.record.value.job.JobRecord in project zeebe by camunda.
the class JobCompleteProcessor method acceptCommand.
private void acceptCommand(final TypedRecord<JobRecord> command, final CommandControl<JobRecord> commandControl) {
final long jobKey = command.getKey();
final JobRecord job = jobState.getJob(jobKey);
job.setVariables(command.getValue().getVariablesBuffer());
commandControl.accept(JobIntent.COMPLETED, job);
jobMetrics.jobCompleted(job.getType());
}
use of io.camunda.zeebe.protocol.impl.record.value.job.JobRecord in project zeebe by camunda.
the class ExporterDirectorTest method shouldApplyRecordFilter.
@Test
public void shouldApplyRecordFilter() {
// given
exporters.get(0).onConfigure(withFilter(Arrays.asList(RecordType.COMMAND, RecordType.EVENT), Collections.singletonList(ValueType.DEPLOYMENT)));
exporters.get(1).onConfigure(withFilter(Collections.singletonList(RecordType.EVENT), Arrays.asList(ValueType.DEPLOYMENT, ValueType.JOB)));
startExporterDirector(exporterDescriptors);
// when
final long deploymentCommand = rule.writeCommand(DeploymentIntent.CREATE, new DeploymentRecord());
final long deploymentEvent = rule.writeEvent(DeploymentIntent.CREATED, new DeploymentRecord());
rule.writeEvent(IncidentIntent.CREATED, new IncidentRecord());
final long jobEvent = rule.writeEvent(JobIntent.CREATED, new JobRecord());
// then
waitUntil(() -> exporters.get(1).getExportedRecords().size() == 2);
assertThat(exporters.get(0).getExportedRecords()).extracting(Record::getPosition).hasSize(2).contains(deploymentCommand, deploymentEvent);
assertThat(exporters.get(1).getExportedRecords()).extracting(Record::getPosition).hasSize(2).contains(deploymentEvent, jobEvent);
}
use of io.camunda.zeebe.protocol.impl.record.value.job.JobRecord in project zeebe by camunda.
the class DbJobState method visitJob.
boolean visitJob(final long jobKey, final BiPredicate<Long, JobRecord> callback, final Runnable cleanupRunnable) {
final JobRecord job = getJob(jobKey);
if (job == null) {
LOG.error("Expected to find job with key {}, but no job found", jobKey);
cleanupRunnable.run();
// we want to continue with the iteration
return true;
}
return callback.test(jobKey, job);
}
Aggregations