Comments (26)
I published another new version - it turns out supporting the command line and programmatic usage is tricky - because at the command line the process can die, but you still want it to keep the lock. I only started supporting command line usage 2 weeks ago or so.
from live-mutex.
Works great for my multi key race right now!
from live-mutex.
Ah interesting, that was experimental code that wasn't supposed to make it into production.
Let me fix it.
In the meantime, change it to this one line, and see if the problem goes away:
this.lockInternal.apply(this, arguments);
just go into:
node_modules/live-mutex/dist/client.js
and modify the file. I will publish something new in a few minutes.
from live-mutex.
yes, it works.
from live-mutex.
ok good, try installing this new version:
I just published it. I made some changes to the codebase in the last 10 days, so it's not exactly the most stable thing, let me know if you see anything strange.
One reason why the deadlock might occur at 5, is if you never call unlock()
, by the way. But don't worry about that right now. The request queuing in the client is an optimization that doesn't need to happen yet.
from live-mutex.
work well!
I got more error/questions.
-
The client option in the typescript definition got ttl option but if i pass ttl, it will fail with
Error: An option passed to Live-Mutex Client constructor is not a recognized option => "ttl"
ttl can be passed with lockp without a problem -
The ttl should be infinity by default in my opinion. Took me a while to recognize that it will unlock itself!!!
-
I can only bind the process with 'warning' event but not 'error'.
process.on('warning', err => {
console.log(err);
});
I got the following typescript compile error if change 'warning' to 'error'
Argument of type '"error"' is not assignable to parameter of type 'Signals'
from live-mutex.
@hkjeffchan yes live-mutex is really performant for certain niche use cases, not just in speed, but CPU usage.
the compilation error is probably for Node.js core types, live-mutex is currently compiling without errors.
to skip typescript compilation for libraries (everything in node_modules) use this option skipLibCheck:true
in your tsconfig.json.
Yeah let me think about the ttl
default. Basically this library has a sweet spot where critical sections take less than about 5 seconds.
For now, maybe set your ttl
to 20000 (20 seconds) or whatever you need.
let me get back to you on the other things in an hour or so.
from live-mutex.
I think I will change the ttl
default to something like 100 seconds, and make a note of that in the README.
from live-mutex.
@hkjeffchan I fixed it - ttl
option to the Client constructor is now fine, that was an options validation bug.
Also, you should only use process.on('warning')
, I removed the warning in the codebase - you do not need to listen for process.on('error')
anymore.
install a new version:
that new version has your fixes.
from live-mutex.
It seems it is completely broken right now.
import { Client } from 'live-mutex';
import * as delay from 'delay';
const mc1 = new Client({
port: 9394,
host: '127.0.0.1'
});
mc1.ensure().then(b => {
b.lockp('a', {ttl: 800000}).then(async res => {
console.log(`mc1 locked`);
await delay(10000);
b.unlockp('a').then(_ => {
console.log('mc1 unlocked');
process.exit(0);
})
})
})
When I try to run it in different console, when process A unlock, process B and C both get the lock at the same time! And sometimes A unlock while B is waiting, B will get the lock but C can get the lock again.
from live-mutex.
[email protected] seems to be working fine
from live-mutex.
can confirm:
[email protected] is the last version to be working correctly
newer version will cause two processes to acquire the lock at the same time!
from live-mutex.
hmmm thanks, let me take a look. can you share your code that can demonstrate the problem on version 0.0.10041
?
from live-mutex.
@hkjeffchan I see the problem you describe on versions [email protected]
through [email protected]
.
I am going to try to fix it. In the meantime I would not use this lib for anything critical :)
btw, if you are using the library for command line purposes, you should use the command line tools:
# in shell 1
lm_start_server 6970
# in shell 2
lm_acquire_lock foo
lm_release_lock foo
from live-mutex.
I found the problem - when a process dies (process.exit(x)
), live-mutex has to be careful to make sure that the process that dies was not holding any locks. if the dead process was holding locks we have to release those locks, unless the user tells the library to keep the lock.
in your situation with A
, B
, and C
. A
unlocked the lock and then the process died. When A
unlocked the lock, it gave the lock to B
. But when A
died, a routine in the broker unlocked the lock and gave it to C
.
I fixed the routine to ensure that if a process died, the lock will only be unlocked if the lock was held by the process that died, there was a bug that unlocked the lock even if the process that died wasn't holding the lock.
from live-mutex.
Seems like the lock is never timeout now.
tried different value with lockRequestTimeout
from live-mutex.
Thanks you have given me really valuable feedback. Sorry the library is not up to par. I made a couple more fixes.
Right now, at the command line, this pattern will work:
"use strict";
const lmx = require("live-mutex");
const Bluebird = require('bluebird');
const c = new lmx.Client({
port: 6970,
});
process.once('warning', function (e) {
console.error('process warning:', e && e.message || e);
});
process.once('unhandledRejection', function (e) {
console.error('unhandledRejection:', e && e.message || e);
process.exit(1);
});
process.once('uncaughtException', function (e) {
console.error('uncaughtException:', e && e.message || e);
process.exit(1);
});
c.emitter.on('warning', function () {
console.warn('lmx warning:', ...arguments);
});
c.ensure().then(c => {
return c.lockp('a', {ttl: 800000, keepLocksAfterDeath: true});
})
.then(async res => {
console.log(`mc1 locked, res.acquired`, res.acquired);
await Bluebird.delay(10000);
return c.unlockp('a').then(_ => {
console.log('mc1 unlocked');
process.exit(0);
});
});
If you want ttl to be Infininity, use:
c.lockp('a', {ttl: Infinity, keepLocksAfterDeath: true});
or
c.lockp('a', {ttl: null, keepLocksAfterDeath: true});
null/Infinity mean the same thing.
keepLocksAfterDeath
after means that if this process dies before unlocking 'a', the broker will not automatically unlock 'a', the lock will remain.
from live-mutex.
from live-mutex.
client option ttl does not support Infinity right now, null is ok.
By the way, this client ttl option is the default for the lockp, right? If client ttl is infinity, the lockp does not need to pass ttl value, right?
UnhandledPromiseRejectionWarning: AssertionError [ERR_ASSERTION]: => "ttl" option needs to be an integer (representing milliseconds).
from live-mutex.
If I pass ttl with Infinity to lockp, it will break. More than 1 process can acquire the lock. It seems it release the lock itself.
from live-mutex.
pass "null" or "infinity" cause the problem, it is working fine if i use 800000 as ttl
it starts to report the following error with null/infinity, so it seems the lock dies and releases itself automatically.
Error: You need to pass the correct uuid, or use force.
from live-mutex.
Ok let me fix it lol, thanks for your patience
from live-mutex.
The fixes should be implemented in this new version:
from live-mutex.
:)
Passing Infinity to lockp cannot acquire the lock at all, passing 800000 will run correctly
from live-mutex.
Ok keep passing 800000 then :) I will see what the problem is
from live-mutex.
@hkjeffchan I am going close this issue and create a new issue for Infinity
failing to work.
Btw, if you're willing to share your project codebase I can tell you if the code looks good / if you are using this library optimally etc.
from live-mutex.
Related Issues (20)
- Client: cannot set no retries or zero retries HOT 6
- Windows HOT 3
- if client experiences error event there should be no more retries for a lock
- if client and server have a version mismatch log this on both client and server
- implement tls HOT 1
- Docker image base from node:alpine HOT 14
- Simulate client and broker side errors to ensure client recovers
- Broker: Memory leak when sockets never disconnect HOT 8
- [feature] ttl per lock HOT 2
- [feature] strict mode & API HOT 3
- Add '@oresoftware/cli' and '@oresoftware/deep.mixin'
- fast-json / fast-stringify
- EADDRINUSE HOT 11
- timeout not taking into effect? HOT 8
- EADDRINUSE: address already in use udsPath HOT 5
- { TypeError: assert.strict is not a function HOT 12
- [Help wanted] An extremely basic and trivial example for locking a file? HOT 2
- write-preferring-rw-lock does not work with nested read locks. HOT 3
- Feature request: add option to disable logging HOT 14
- On some systems UDS socket opening fails with ENOENT exception
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from live-mutex.