Please don't deprecate release() function
See original GitHub issueWith great power comes great responsibility…says Batman I think 😉
I get it, runExclusive ensures you don’t screw things up and not unlock the thread, but sometimes you can’t set things up with a nice try / catch loop and you really need to use withTimeout to ensure it doesn’t lock the application.
Here is an example from React Native that I made as a workaround for this Expo issue:
import React, {useCallback, useRef, useState} from "react";
import {MutexInterface, withTimeout, Mutex} from "async-mutex";
import {Video} from "expo-av";
import {Asset} from "expo-media-library";
type IVideoInfo = Pick<Asset, "width" | "height" | "duration">;
const useVideoInfo = () => {
const [uri, setUri] = useState<string>();
// const mutexRef = useRef<MutexInterface>(withTimeout(new Mutex(), 4000));
// withTimeout didn't really seem to be working...so we just set a timeout
const mutexRef = useRef<MutexInterface>(new Mutex());
const videoInfoRef = useRef<IVideoInfo>();
const getVideoInfo = useCallback(
async (uri: string) => {
mutexRef.current.release();
videoInfoRef.current = undefined;
await mutexRef.current.acquire();
setTimeout(() => mutexRef.current.release(), 5000);
setUri(uri);
await mutexRef.current.waitForUnlock();
if (!videoInfoRef.current) {
throw(`Could not extract the video info from ${uri}`)
}
return videoInfoRef.current;
},
[],
);
const VideoInfoExtractor = useCallback(
() => <Video
style={{width: 1, height: 1, opacity: 1}}
source={{ uri }}
onReadyForDisplay={event => {
if (event.status?.isLoaded) {
const { width, height } = event.naturalSize;
videoInfoRef.current = {width, height, duration: event.status.durationMillis / 1000};
mutexRef.current.release();
}
}}
/>,
[uri],
);
return {
VideoInfoExtractor,
getVideoInfo,
};
};
export {
useVideoInfo,
IVideoInfo,
};
Rewriting this somehow with runExclusive would basically fly in the face of what I’m trying to do here which is wait for one thing to wait for another.
Can we keep the acquire/release paradigm into the future? 🙏
PS. For some reason the withTimeout wrapper didn’t work for me…so I had to use setTimeout…maybe I’m doing something wrong?
Issue Analytics
- State:
- Created 2 years ago
- Reactions:7
- Comments:7 (3 by maintainers)
Top Results From Across the Web
Deprecate functions and arguments — deprecate_soft • lifecycle
A string giving the version when the behaviour was deprecated. what. A string describing what is deprecated: Deprecate a whole function with "foo()"...
Read more >How and When to Deprecate APIs - Oracle Help Center
Java provides a way to express deprecation because, as a class evolves, its API (application programming interface) inevitably changes: methods are renamed for ......
Read more >Deprecating changes for 1 release instead of removing #383
@trigger_error('XXX() is deprecated since version 2.8 and will be removed in 3.0. Use XXX instead.', E_USER_DEPRECATED);.
Read more >How to mark a method as obsolete or deprecated?
The shortest way is by adding the ObsoleteAttribute as an attribute to the method. Make sure to include an appropriate explanation: [Obsolete("Method1 is ......
Read more >What is deprecated in IT? - TechTarget
In information technology (IT), deprecation means that although something is available or allowed, it is not recommended or that -- in the case...
Read more >Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start FreeTop Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Top GitHub Comments
It continue to be surprised by the way this library is used in projects 😏
A bit of background on why I have been planning to remove
Mutex::release
(the same holds true forSemaphore
). This library originally was intended for limiting concurrency in critical sections of code. To that end, the original API did not containMutex::release
; instead,Mutex::acquire
returns a dedicated release callback that is scoped to the individual lock acquired byacquire
. This has the benefit of being idempotent: multiple calls will have no effect, even if the mutex has been locked again. In order to have a RAII type approach to unlocking, I also addedrunExclusive
from the start.I only added
Mutex::release
when people started requesting it in order to avoid managing the individual releasers returned by subsequent calls toacquire
. When I added it I was in a hurry, and I only later realized that this use case is much better served byrunExclusive
. So, I decided to deprecate and remove it again.However, judging from your example (and from other requests for keeping this function) it seems that people are now also using the library now to notify waiters when a task has completed, and this cannot be refactored to use
runExclusive
(and scoped releasers are awkward in this case). I guess I can’t really go back and remove that function again. So, worry not, I’ll keep it (and probably also make it work properly for nontrivial semaphores) 😏 I’ll remove the annotation and adapt the documentation when I next update the library.As for using the semaphore as a condition variable: I would much rather add an async queue to the library. You would call
await queue.next()
to wait for the next value to be pushed into the queue, and callingqueue.push(...)
would push the next value into the queue. New values would be distributed to waiters in a first come, first served fashion. I think this would probably cover all use cases that I have seen where mutex / semaphore are used for notification rather than for limiting concurrency. Would that fit your shoe?+1 please please don’t deprecate
release
😃release
(to use, um, boomer language,V
) beforeacquire
(P
) on a semaphore initialized to zero can be used to get (effectively) condition variables, which is pretty nice to have sinceasync-mutex
doesn’t implement those directly.