"use strict" ;
const Promise = require ( "bluebird" ) ;
// const { UniqueViolationError } = require("objection");
const pipe = require ( "@promistream/pipe" ) ;
const map = require ( "@promistream/map" ) ;
const mapFilter = require ( "@promistream/map-filter" ) ;
module . exports = function ( { backend } ) {
return function processTaskSafely ( task , processHandler ) {
let lockStream = mapFilter ( ( item ) => {
return Promise . try ( ( ) => {
return backend . lock ( null , { id : item . id , task : task } ) ;
} ) . then ( ( success ) => {
if ( success ) {
return item ;
} else {
return mapFilter . NoValue ;
}
} ) ;
} ) ;
let processUnlockStream = map ( ( item ) => {
return Promise . try ( ( ) => {
return backend . runInTransaction ( ( tx ) => {
return processHandler ( item , tx ) ;
} ) ;
} ) . finally ( ( ) => {
// NOTE: The unlock deliberately happens outside of a transaction, so that it can always succeed, even if a task and its associated database changes failed
return backend . unlock ( null , { id : item . id , task : task } ) ;
} ) . then ( ( ) => {
return item ;
} ) ;
} ) ;
return pipe ( [
lockStream ,
processUnlockStream
] ) ;
} ;
} ;