mirror of
https://github.com/hyperledger/fabric-samples.git
synced 2026-06-21 00:55:10 +00:00
Add comments to jobs.ts
Signed-off-by: James Taylor <jamest@uk.ibm.com>
This commit is contained in:
parent
5447e3534d
commit
dfe79f7fb4
1 changed files with 144 additions and 126 deletions
|
|
@ -26,7 +26,6 @@ export type JobResult = {
|
||||||
transactionError?: string;
|
transactionError?: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
// TODO include attempts made?
|
|
||||||
export type JobSummary = {
|
export type JobSummary = {
|
||||||
jobId: string;
|
jobId: string;
|
||||||
transactionIds: string[];
|
transactionIds: string[];
|
||||||
|
|
@ -53,6 +52,9 @@ const connection: ConnectionOptions = {
|
||||||
password: config.redisPassword,
|
password: config.redisPassword,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Set up the queue for submit jobs
|
||||||
|
*/
|
||||||
export const initJobQueue = (): Queue => {
|
export const initJobQueue = (): Queue => {
|
||||||
const submitQueue = new Queue(config.JOB_QUEUE_NAME, {
|
const submitQueue = new Queue(config.JOB_QUEUE_NAME, {
|
||||||
connection,
|
connection,
|
||||||
|
|
@ -70,6 +72,10 @@ export const initJobQueue = (): Queue => {
|
||||||
return submitQueue;
|
return submitQueue;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Set up a worker to process submit jobs on the queue, using the
|
||||||
|
* processSubmitTransactionJob function below
|
||||||
|
*/
|
||||||
export const initJobQueueWorker = (app: Application): Worker => {
|
export const initJobQueueWorker = (app: Application): Worker => {
|
||||||
const worker = new Worker<JobData, JobResult>(
|
const worker = new Worker<JobData, JobResult>(
|
||||||
config.JOB_QUEUE_NAME,
|
config.JOB_QUEUE_NAME,
|
||||||
|
|
@ -80,7 +86,7 @@ export const initJobQueueWorker = (app: Application): Worker => {
|
||||||
);
|
);
|
||||||
|
|
||||||
worker.on('failed', (job) => {
|
worker.on('failed', (job) => {
|
||||||
logger.error({ job }, 'Job failed'); // WHY?!
|
logger.warn({ job }, 'Job failed');
|
||||||
});
|
});
|
||||||
|
|
||||||
// Important: need to handle this error otherwise worker may stop
|
// Important: need to handle this error otherwise worker may stop
|
||||||
|
|
@ -98,130 +104,6 @@ export const initJobQueueWorker = (app: Application): Worker => {
|
||||||
return worker;
|
return worker;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const initJobQueueScheduler = (): QueueScheduler => {
|
|
||||||
const queueScheduler = new QueueScheduler(config.JOB_QUEUE_NAME, {
|
|
||||||
connection,
|
|
||||||
});
|
|
||||||
|
|
||||||
queueScheduler.on('failed', (jobId, failedReason) => {
|
|
||||||
// TODO when does this happen, and how should it be handled?
|
|
||||||
logger.error({ jobId, failedReason }, 'Queue sceduler failure');
|
|
||||||
});
|
|
||||||
|
|
||||||
return queueScheduler;
|
|
||||||
};
|
|
||||||
|
|
||||||
export const addSubmitTransactionJob = async (
|
|
||||||
submitQueue: Queue<JobData, JobResult>,
|
|
||||||
mspid: string,
|
|
||||||
transactionName: string,
|
|
||||||
...transactionArgs: string[]
|
|
||||||
): Promise<string> => {
|
|
||||||
const jobName = `submit ${transactionName} transaction`;
|
|
||||||
const job = await submitQueue.add(jobName, {
|
|
||||||
mspid,
|
|
||||||
transactionName,
|
|
||||||
transactionArgs: transactionArgs,
|
|
||||||
transactionIds: [],
|
|
||||||
});
|
|
||||||
|
|
||||||
if (job?.id === undefined) {
|
|
||||||
throw new Error('Submit transaction job ID not available');
|
|
||||||
}
|
|
||||||
|
|
||||||
return job.id;
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Gets a summary for the jobs endpoint
|
|
||||||
*/
|
|
||||||
export const getJobSummary = async (
|
|
||||||
queue: Queue,
|
|
||||||
jobId: string
|
|
||||||
): Promise<JobSummary> => {
|
|
||||||
const job: Job<JobData, JobResult> | undefined = await queue.getJob(jobId);
|
|
||||||
logger.debug({ job }, 'Got job');
|
|
||||||
|
|
||||||
if (!(job && job.id != undefined)) {
|
|
||||||
throw new JobNotFoundError(`Job ${jobId} not found`, jobId);
|
|
||||||
}
|
|
||||||
|
|
||||||
let transactionIds: string[];
|
|
||||||
if (job.data && job.data.transactionIds) {
|
|
||||||
transactionIds = job.data.transactionIds;
|
|
||||||
} else {
|
|
||||||
transactionIds = [];
|
|
||||||
}
|
|
||||||
|
|
||||||
let transactionError;
|
|
||||||
let transactionPayload;
|
|
||||||
const returnValue = job.returnvalue;
|
|
||||||
if (returnValue) {
|
|
||||||
if (returnValue.transactionError) {
|
|
||||||
transactionError = returnValue.transactionError;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (
|
|
||||||
returnValue.transactionPayload &&
|
|
||||||
returnValue.transactionPayload.length > 0
|
|
||||||
) {
|
|
||||||
transactionPayload = returnValue.transactionPayload.toString();
|
|
||||||
} else {
|
|
||||||
transactionPayload = '';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const jobSummary: JobSummary = {
|
|
||||||
jobId: job.id,
|
|
||||||
transactionIds,
|
|
||||||
transactionError,
|
|
||||||
transactionPayload,
|
|
||||||
};
|
|
||||||
|
|
||||||
return jobSummary;
|
|
||||||
};
|
|
||||||
|
|
||||||
export const updateJobData = async (
|
|
||||||
job: Job<JobData, JobResult>,
|
|
||||||
transaction: Transaction | undefined
|
|
||||||
): Promise<void> => {
|
|
||||||
const newData = { ...job.data };
|
|
||||||
|
|
||||||
if (transaction != undefined) {
|
|
||||||
const transationIds = ([] as string[]).concat(
|
|
||||||
newData.transactionIds,
|
|
||||||
transaction.getTransactionId()
|
|
||||||
);
|
|
||||||
newData.transactionIds = transationIds;
|
|
||||||
|
|
||||||
newData.transactionState = transaction.serialize();
|
|
||||||
} else {
|
|
||||||
newData.transactionState = undefined;
|
|
||||||
}
|
|
||||||
|
|
||||||
await job.update(newData);
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Get the current job counts
|
|
||||||
*
|
|
||||||
* This function is used for the liveness REST endpoint
|
|
||||||
*/
|
|
||||||
export const getJobCounts = async (
|
|
||||||
queue: Queue
|
|
||||||
): Promise<{ [index: string]: number }> => {
|
|
||||||
const jobCounts = await queue.getJobCounts(
|
|
||||||
'active',
|
|
||||||
'completed',
|
|
||||||
'delayed',
|
|
||||||
'failed',
|
|
||||||
'waiting'
|
|
||||||
);
|
|
||||||
logger.debug({ jobCounts }, 'Current job counts');
|
|
||||||
|
|
||||||
return jobCounts;
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Process a submit transaction request from the job queue
|
* Process a submit transaction request from the job queue
|
||||||
*
|
*
|
||||||
|
|
@ -326,3 +208,139 @@ export const processSubmitTransactionJob = async (
|
||||||
throw err;
|
throw err;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Set up a scheduler for the submit job queue
|
||||||
|
*
|
||||||
|
* This manages stalled and delayed jobs and is required for retries with backoff
|
||||||
|
*/
|
||||||
|
export const initJobQueueScheduler = (): QueueScheduler => {
|
||||||
|
const queueScheduler = new QueueScheduler(config.JOB_QUEUE_NAME, {
|
||||||
|
connection,
|
||||||
|
});
|
||||||
|
|
||||||
|
queueScheduler.on('failed', (jobId, failedReason) => {
|
||||||
|
logger.error({ jobId, failedReason }, 'Queue sceduler failure');
|
||||||
|
});
|
||||||
|
|
||||||
|
return queueScheduler;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Helper to add a new submit transaction job to the queue
|
||||||
|
*/
|
||||||
|
export const addSubmitTransactionJob = async (
|
||||||
|
submitQueue: Queue<JobData, JobResult>,
|
||||||
|
mspid: string,
|
||||||
|
transactionName: string,
|
||||||
|
...transactionArgs: string[]
|
||||||
|
): Promise<string> => {
|
||||||
|
const jobName = `submit ${transactionName} transaction`;
|
||||||
|
const job = await submitQueue.add(jobName, {
|
||||||
|
mspid,
|
||||||
|
transactionName,
|
||||||
|
transactionArgs: transactionArgs,
|
||||||
|
transactionIds: [],
|
||||||
|
});
|
||||||
|
|
||||||
|
if (job?.id === undefined) {
|
||||||
|
throw new Error('Submit transaction job ID not available');
|
||||||
|
}
|
||||||
|
|
||||||
|
return job.id;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Helper to update the data for an existing job
|
||||||
|
*/
|
||||||
|
export const updateJobData = async (
|
||||||
|
job: Job<JobData, JobResult>,
|
||||||
|
transaction: Transaction | undefined
|
||||||
|
): Promise<void> => {
|
||||||
|
const newData = { ...job.data };
|
||||||
|
|
||||||
|
if (transaction != undefined) {
|
||||||
|
const transationIds = ([] as string[]).concat(
|
||||||
|
newData.transactionIds,
|
||||||
|
transaction.getTransactionId()
|
||||||
|
);
|
||||||
|
newData.transactionIds = transationIds;
|
||||||
|
|
||||||
|
newData.transactionState = transaction.serialize();
|
||||||
|
} else {
|
||||||
|
newData.transactionState = undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
await job.update(newData);
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Gets a job summary
|
||||||
|
*
|
||||||
|
* This function is used for the jobs REST endpoint
|
||||||
|
*/
|
||||||
|
export const getJobSummary = async (
|
||||||
|
queue: Queue,
|
||||||
|
jobId: string
|
||||||
|
): Promise<JobSummary> => {
|
||||||
|
const job: Job<JobData, JobResult> | undefined = await queue.getJob(jobId);
|
||||||
|
logger.debug({ job }, 'Got job');
|
||||||
|
|
||||||
|
if (!(job && job.id != undefined)) {
|
||||||
|
throw new JobNotFoundError(`Job ${jobId} not found`, jobId);
|
||||||
|
}
|
||||||
|
|
||||||
|
let transactionIds: string[];
|
||||||
|
if (job.data && job.data.transactionIds) {
|
||||||
|
transactionIds = job.data.transactionIds;
|
||||||
|
} else {
|
||||||
|
transactionIds = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
let transactionError;
|
||||||
|
let transactionPayload;
|
||||||
|
const returnValue = job.returnvalue;
|
||||||
|
if (returnValue) {
|
||||||
|
if (returnValue.transactionError) {
|
||||||
|
transactionError = returnValue.transactionError;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
returnValue.transactionPayload &&
|
||||||
|
returnValue.transactionPayload.length > 0
|
||||||
|
) {
|
||||||
|
transactionPayload = returnValue.transactionPayload.toString();
|
||||||
|
} else {
|
||||||
|
transactionPayload = '';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const jobSummary: JobSummary = {
|
||||||
|
jobId: job.id,
|
||||||
|
transactionIds,
|
||||||
|
transactionError,
|
||||||
|
transactionPayload,
|
||||||
|
};
|
||||||
|
|
||||||
|
return jobSummary;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Get the current job counts
|
||||||
|
*
|
||||||
|
* This function is used for the liveness REST endpoint
|
||||||
|
*/
|
||||||
|
export const getJobCounts = async (
|
||||||
|
queue: Queue
|
||||||
|
): Promise<{ [index: string]: number }> => {
|
||||||
|
const jobCounts = await queue.getJobCounts(
|
||||||
|
'active',
|
||||||
|
'completed',
|
||||||
|
'delayed',
|
||||||
|
'failed',
|
||||||
|
'waiting'
|
||||||
|
);
|
||||||
|
logger.debug({ jobCounts }, 'Current job counts');
|
||||||
|
|
||||||
|
return jobCounts;
|
||||||
|
};
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue