1+ import { useCallback , useEffect , useState } from "react"
2+ import { useLock } from "../../../../../../packages/react-tools/src" ;
3+
4+ /**
5+ The component uses _useLock_ hook to simulate a buffer write by a producer and read from a consumer.
6+ */
7+ export const UseLock = ( ) => {
8+ const [ buffer , setBuffer ] = useState < number [ ] > ( [ ] ) ;
9+ const [ lock , setLock ] = useState < { held : string [ ] , pending : string [ ] } > ( { held : [ ] , pending : [ ] } ) ;
10+ const [ messages , setMessages ] = useState < { consumer : string [ ] , producer : string [ ] } > ( {
11+ consumer : [ ] ,
12+ producer : [ ]
13+ } ) ;
14+ const do_something = useCallback ( ( mode : "read" | "write" ) => {
15+ return new Promise < void > ( ( res ) => {
16+ setTimeout ( ( ) => {
17+ if ( mode === "read" ) {
18+ let el : number | undefined ;
19+ setBuffer ( b => b . filter ( ( _ , index , arr ) => {
20+ if ( index !== arr . length - 1 ) {
21+ return true ;
22+ } else {
23+ el = _ ;
24+ return false ;
25+ }
26+ } ) )
27+ setMessages ( m => ( { ...m , consumer : [ ...m . consumer , el !== undefined ? "Consumer has read " + el : "Consumer has read nothing" ] } ) )
28+ } else {
29+ const n = Math . floor ( Math . random ( ) * 11 ) ;
30+ setBuffer ( b => [ ...b , n ] ) ;
31+ setMessages ( m => ( { ...m , producer : [ ...m . producer , "Producer has written " + n ] } ) ) ;
32+ }
33+ res ( ) ;
34+ } , mode === "read" ? 1600 : 2400 ) ;
35+ } ) ;
36+ } , [ ] ) ;
37+
38+ const [ createExclusiveLock , query ] = useLock ( "resource" , async ( ) => {
39+ await do_something ( "write" ) ;
40+ } ) ;
41+
42+ const [ createSharedLock ] = useLock ( "resource" , async ( ) => {
43+ await do_something ( "read" ) ;
44+ } , { mode : "shared" } ) ;
45+
46+ useEffect ( ( ) => {
47+ const interval = setInterval ( async ( ) => {
48+ const n = Math . floor ( Math . random ( ) * 11 ) ;
49+ n > 6 ? createExclusiveLock ( ) : createSharedLock ( ) ;
50+ } , 700 ) ;
51+ return ( ) => clearInterval ( interval ) ;
52+ } , [ createExclusiveLock , createSharedLock ] ) ;
53+
54+ useEffect ( ( ) => {
55+ const interval = setInterval ( async ( ) => {
56+ const result = await query ( ) ;
57+ const held = ( result . held || [ ] ) . map ( el => el . name + " - " + el . mode ) ;
58+ const pending = ( result . pending || [ ] ) . map ( el => el . name + " - " + el . mode ) ;
59+ setLock ( { held, pending } ) ;
60+ } , 1000 )
61+ return ( ) => {
62+ clearInterval ( interval )
63+ }
64+ } , [ query ] ) ;
65+
66+ return < div >
67+ < div style = { { marginTop : 30 , display : "grid" , gridTemplateColumns : "auto auto auto auto auto" , justifyContent : "center" , gap : 50 , overflow : 'auto' , maxHeight : 400 } } >
68+ < div style = { { overflow : 'auto' , maxHeight : 400 } } >
69+ < h3 > Producer</ h3 >
70+ {
71+ messages . producer . map ( ( m , index ) => < p key = { index } > { m } </ p > )
72+ }
73+ </ div >
74+ < div >
75+ < h3 > Buffer</ h3 >
76+ < p > { JSON . stringify ( buffer , null , 6 ) } </ p >
77+ </ div >
78+ < div style = { { display : "grid" , gridTemplateColumns : "auto" , justifyContent : "center" , gap : 50 , overflow : 'auto' , maxHeight : 400 } } >
79+ < div >
80+ < h3 > Consumer </ h3 >
81+ {
82+ messages . consumer . map ( ( m , index ) => < p key = { index } > { m } </ p > )
83+ }
84+ </ div >
85+ </ div >
86+ < div style = { { overflow : 'auto' , maxHeight : 400 } } >
87+ < h4 > Held Lock</ h4 >
88+ {
89+ lock . held . map ( ( el , index ) => < p key = { index } > { el } </ p > )
90+ }
91+ </ div >
92+ < div style = { { overflow : 'auto' , maxHeight : 400 } } >
93+ < h4 > Pending Lock</ h4 >
94+ {
95+ lock . pending . map ( ( el , index ) => < p key = { index } > { el } </ p > )
96+ }
97+ </ div >
98+ </ div >
99+ </ div >
100+ }
0 commit comments