atomically
Advanced tools
Comparing version 1.4.0 to 1.5.0
@@ -0,5 +1,15 @@ | ||
/// <reference types="node" /> | ||
declare const RetryfyQueue: { | ||
queue: Set<unknown>; | ||
schedule: (id: any, limit?: number) => Promise<Function>; | ||
interval: number; | ||
intervalId: NodeJS.Timeout | undefined; | ||
limit: number; | ||
queueActive: Set<Function>; | ||
queueWaiting: Set<Function>; | ||
init: () => void; | ||
reset: () => void; | ||
add: (fn: Function) => void; | ||
remove: (fn: Function) => void; | ||
schedule: () => Promise<Function>; | ||
tick: () => void; | ||
}; | ||
export default RetryfyQueue; |
@@ -7,14 +7,50 @@ "use strict"; | ||
const RetryfyQueue = { | ||
queue: new Set(), | ||
schedule: (id, limit = consts_1.LIMIT_FILES_DESCRIPTORS) => { | ||
const add = () => RetryfyQueue.queue.add(id), remove = () => RetryfyQueue.queue.delete(id); | ||
interval: 25, | ||
intervalId: undefined, | ||
limit: consts_1.LIMIT_FILES_DESCRIPTORS, | ||
queueActive: new Set(), | ||
queueWaiting: new Set(), | ||
init: () => { | ||
if (RetryfyQueue.intervalId) | ||
return; | ||
RetryfyQueue.intervalId = setInterval(RetryfyQueue.tick, RetryfyQueue.interval); | ||
}, | ||
reset: () => { | ||
if (!RetryfyQueue.intervalId) | ||
return; | ||
clearInterval(RetryfyQueue.intervalId); | ||
delete RetryfyQueue.intervalId; | ||
}, | ||
add: (fn) => { | ||
RetryfyQueue.queueWaiting.add(fn); | ||
if (RetryfyQueue.queueActive.size < (RetryfyQueue.limit / 2)) { // Active queue not under preassure, executing immediately | ||
RetryfyQueue.tick(); | ||
} | ||
else { | ||
RetryfyQueue.init(); | ||
} | ||
}, | ||
remove: (fn) => { | ||
RetryfyQueue.queueWaiting.delete(fn); | ||
RetryfyQueue.queueActive.delete(fn); | ||
}, | ||
schedule: () => { | ||
return new Promise(resolve => { | ||
const check = () => { | ||
if (RetryfyQueue.queue.size >= limit) | ||
return setTimeout(check, 150); | ||
add(); | ||
resolve(remove); | ||
}; | ||
check(); | ||
const cleanup = () => RetryfyQueue.remove(resolver); | ||
const resolver = () => resolve(cleanup); | ||
RetryfyQueue.add(resolver); | ||
}); | ||
}, | ||
tick: () => { | ||
if (RetryfyQueue.queueActive.size >= RetryfyQueue.limit) | ||
return; | ||
if (!RetryfyQueue.queueWaiting.size) | ||
return RetryfyQueue.reset(); | ||
for (const fn of RetryfyQueue.queueWaiting) { | ||
if (RetryfyQueue.queueActive.size >= RetryfyQueue.limit) | ||
break; | ||
RetryfyQueue.queueWaiting.delete(fn); | ||
RetryfyQueue.queueActive.add(fn); | ||
fn(); | ||
} | ||
} | ||
@@ -21,0 +57,0 @@ }; |
@@ -10,3 +10,3 @@ "use strict"; | ||
return function attempt() { | ||
return retryify_queue_1.default.schedule(attempt).then(cleanup => { | ||
return retryify_queue_1.default.schedule().then(cleanup => { | ||
return fn.apply(undefined, arguments).then(result => { | ||
@@ -13,0 +13,0 @@ cleanup(); |
{ | ||
"name": "atomically", | ||
"description": "Read and write files atomically and reliably.", | ||
"version": "1.4.0", | ||
"version": "1.5.0", | ||
"main": "dist/index.js", | ||
@@ -6,0 +6,0 @@ "types": "dist/index.d.ts", |
@@ -10,24 +10,81 @@ | ||
queue: new Set (), | ||
interval: 25, | ||
intervalId: <NodeJS.Timeout | undefined> undefined, | ||
limit: LIMIT_FILES_DESCRIPTORS, | ||
queueActive: new Set<Function> (), | ||
queueWaiting: new Set<Function> (), | ||
schedule: ( id: any, limit: number = LIMIT_FILES_DESCRIPTORS ): Promise<Function> => { | ||
init: (): void => { | ||
const add = () => RetryfyQueue.queue.add ( id ), | ||
remove = () => RetryfyQueue.queue.delete ( id ); | ||
if ( RetryfyQueue.intervalId ) return; | ||
return new Promise ( resolve => { | ||
RetryfyQueue.intervalId = setInterval ( RetryfyQueue.tick, RetryfyQueue.interval ); | ||
const check = () => { | ||
}, | ||
if ( RetryfyQueue.queue.size >= limit ) return setTimeout ( check, 150 ); | ||
reset: (): void => { | ||
add (); | ||
resolve ( remove ); | ||
if ( !RetryfyQueue.intervalId ) return; | ||
}; | ||
clearInterval ( RetryfyQueue.intervalId ); | ||
check (); | ||
delete RetryfyQueue.intervalId; | ||
}, | ||
add: ( fn: Function ): void => { | ||
RetryfyQueue.queueWaiting.add ( fn ); | ||
if ( RetryfyQueue.queueActive.size < ( RetryfyQueue.limit / 2 ) ) { // Active queue not under preassure, executing immediately | ||
RetryfyQueue.tick (); | ||
} else { | ||
RetryfyQueue.init (); | ||
} | ||
}, | ||
remove: ( fn: Function ): void => { | ||
RetryfyQueue.queueWaiting.delete ( fn ); | ||
RetryfyQueue.queueActive.delete ( fn ); | ||
}, | ||
schedule: (): Promise<Function> => { | ||
return new Promise ( resolve => { | ||
const cleanup = () => RetryfyQueue.remove ( resolver ); | ||
const resolver = () => resolve ( cleanup ); | ||
RetryfyQueue.add ( resolver ); | ||
}); | ||
}, | ||
tick: (): void => { | ||
if ( RetryfyQueue.queueActive.size >= RetryfyQueue.limit ) return; | ||
if ( !RetryfyQueue.queueWaiting.size ) return RetryfyQueue.reset (); | ||
for ( const fn of RetryfyQueue.queueWaiting ) { | ||
if ( RetryfyQueue.queueActive.size >= RetryfyQueue.limit ) break; | ||
RetryfyQueue.queueWaiting.delete ( fn ); | ||
RetryfyQueue.queueActive.add ( fn ); | ||
fn (); | ||
} | ||
} | ||
@@ -34,0 +91,0 @@ |
@@ -15,3 +15,3 @@ | ||
return RetryfyQueue.schedule ( attempt ).then ( cleanup => { | ||
return RetryfyQueue.schedule ().then ( cleanup => { | ||
@@ -18,0 +18,0 @@ return fn.apply ( undefined, arguments ).then ( result => { |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
92802
2076