Giter VIP home page Giter VIP logo

Comments (26)

ORESoftware avatar ORESoftware commented on August 25, 2024 1

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.

hkjeffchan avatar hkjeffchan commented on August 25, 2024 1

Works great for my multi key race right now!

from live-mutex.

ORESoftware avatar ORESoftware commented on August 25, 2024

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.

hkjeffchan avatar hkjeffchan commented on August 25, 2024

yes, it works.

from live-mutex.

ORESoftware avatar ORESoftware commented on August 25, 2024

ok good, try installing this new version:

[email protected]

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.

hkjeffchan avatar hkjeffchan commented on August 25, 2024

work well!

I got more error/questions.

  1. 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

  2. The ttl should be infinity by default in my opinion. Took me a while to recognize that it will unlock itself!!!

  3. 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.

ORESoftware avatar ORESoftware commented on August 25, 2024

@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.

ORESoftware avatar ORESoftware commented on August 25, 2024

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.

ORESoftware avatar ORESoftware commented on August 25, 2024

@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.

hkjeffchan avatar hkjeffchan commented on August 25, 2024

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.

hkjeffchan avatar hkjeffchan commented on August 25, 2024

[email protected] seems to be working fine

from live-mutex.

hkjeffchan avatar hkjeffchan commented on August 25, 2024

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.

ORESoftware avatar ORESoftware commented on August 25, 2024

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.

ORESoftware avatar ORESoftware commented on August 25, 2024

@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.

ORESoftware avatar ORESoftware commented on August 25, 2024

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.

hkjeffchan avatar hkjeffchan commented on August 25, 2024

Seems like the lock is never timeout now.
tried different value with lockRequestTimeout

from live-mutex.

ORESoftware avatar ORESoftware commented on August 25, 2024

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.

ORESoftware avatar ORESoftware commented on August 25, 2024

+ [email protected]

from live-mutex.

hkjeffchan avatar hkjeffchan commented on August 25, 2024

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.

hkjeffchan avatar hkjeffchan commented on August 25, 2024

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.

hkjeffchan avatar hkjeffchan commented on August 25, 2024

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.

ORESoftware avatar ORESoftware commented on August 25, 2024

Ok let me fix it lol, thanks for your patience

from live-mutex.

ORESoftware avatar ORESoftware commented on August 25, 2024

The fixes should be implemented in this new version:

+ [email protected]

from live-mutex.

hkjeffchan avatar hkjeffchan commented on August 25, 2024

:)
Passing Infinity to lockp cannot acquire the lock at all, passing 800000 will run correctly

from live-mutex.

ORESoftware avatar ORESoftware commented on August 25, 2024

Ok keep passing 800000 then :) I will see what the problem is

from live-mutex.

ORESoftware avatar ORESoftware commented on August 25, 2024

@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)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo 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.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.