lightning: use queueing lock
This commit is contained in:
parent
a13fb91ea4
commit
ee576d3ead
@ -28,7 +28,7 @@ import errno
|
|||||||
import random
|
import random
|
||||||
import re
|
import re
|
||||||
import select
|
import select
|
||||||
from collections import defaultdict
|
from collections import defaultdict, deque
|
||||||
import threading
|
import threading
|
||||||
import socket
|
import socket
|
||||||
import json
|
import json
|
||||||
@ -157,6 +157,34 @@ def deserialize_server(server_str):
|
|||||||
def serialize_server(host, port, protocol):
|
def serialize_server(host, port, protocol):
|
||||||
return str(':'.join([host, port, protocol]))
|
return str(':'.join([host, port, protocol]))
|
||||||
|
|
||||||
|
class QLock:
|
||||||
|
def __init__(self):
|
||||||
|
self.lock = threading.Lock()
|
||||||
|
self.waiters = deque()
|
||||||
|
self.count = 0
|
||||||
|
|
||||||
|
def acquire(self):
|
||||||
|
self.lock.acquire()
|
||||||
|
if self.count:
|
||||||
|
new_lock = threading.Lock()
|
||||||
|
new_lock.acquire()
|
||||||
|
self.waiters.append(new_lock)
|
||||||
|
self.lock.release()
|
||||||
|
new_lock.acquire()
|
||||||
|
self.lock.acquire()
|
||||||
|
self.count += 1
|
||||||
|
self.lock.release()
|
||||||
|
|
||||||
|
def release(self):
|
||||||
|
with self.lock:
|
||||||
|
if not self.count:
|
||||||
|
raise ValueError("lock not acquired")
|
||||||
|
self.count -= 1
|
||||||
|
if self.waiters:
|
||||||
|
self.waiters.popleft().release()
|
||||||
|
|
||||||
|
def locked(self):
|
||||||
|
return self.count > 0
|
||||||
|
|
||||||
class Network(util.DaemonThread):
|
class Network(util.DaemonThread):
|
||||||
"""The Network class manages a set of connections to remote electrum
|
"""The Network class manages a set of connections to remote electrum
|
||||||
@ -1063,13 +1091,13 @@ class Network(util.DaemonThread):
|
|||||||
def run(self):
|
def run(self):
|
||||||
self.init_headers_file()
|
self.init_headers_file()
|
||||||
loop = asyncio.new_event_loop()
|
loop = asyncio.new_event_loop()
|
||||||
|
networkAndWalletLock = QLock()
|
||||||
def asyncioThread():
|
def asyncioThread():
|
||||||
asyncio.set_event_loop(loop)
|
asyncio.set_event_loop(loop)
|
||||||
self.lightninglock.acquire()
|
self.lightninglock.acquire()
|
||||||
task = asyncio.ensure_future(asyncio.gather(self.lightningrpc.run(networkAndWalletLock), self.lightningworker.run(networkAndWalletLock)))
|
task = asyncio.ensure_future(asyncio.gather(self.lightningrpc.run(networkAndWalletLock), self.lightningworker.run(networkAndWalletLock)))
|
||||||
loop.run_forever()
|
loop.run_forever()
|
||||||
threading.Thread(target=asyncioThread).start()
|
threading.Thread(target=asyncioThread).start()
|
||||||
networkAndWalletLock = threading.Lock()
|
|
||||||
networkAndWalletLock.acquire()
|
networkAndWalletLock.acquire()
|
||||||
while self.is_running():
|
while self.is_running():
|
||||||
self.maintain_sockets()
|
self.maintain_sockets()
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
import functools
|
import functools
|
||||||
|
import datetime
|
||||||
import sys
|
import sys
|
||||||
import struct
|
import struct
|
||||||
import traceback
|
import traceback
|
||||||
@ -602,7 +603,7 @@ class LightningRPC:
|
|||||||
try:
|
try:
|
||||||
qitem = self.queue.get(block=False)
|
qitem = self.queue.get(block=False)
|
||||||
except queue.Empty:
|
except queue.Empty:
|
||||||
await asyncio.sleep(1)
|
await asyncio.sleep(5)
|
||||||
pass
|
pass
|
||||||
else:
|
else:
|
||||||
def lightningRpcNetworkRequestThreadTarget(qitem):
|
def lightningRpcNetworkRequestThreadTarget(qitem):
|
||||||
@ -686,31 +687,22 @@ class LightningWorker:
|
|||||||
NETWORK = self.network()
|
NETWORK = self.network()
|
||||||
CONFIG = self.config()
|
CONFIG = self.config()
|
||||||
|
|
||||||
netAndWalLock.acquire()
|
|
||||||
synced, local, server = isSynced()
|
|
||||||
netAndWalLock.release()
|
|
||||||
if not synced:
|
|
||||||
await asyncio.sleep(5)
|
|
||||||
continue
|
|
||||||
else:
|
|
||||||
if not wasAlreadyUpToDate:
|
|
||||||
print("UP TO DATE FOR THE FIRST TIME")
|
|
||||||
print(NETWORK.get_status_value("updated"))
|
|
||||||
wasAlreadyUpToDate = True
|
|
||||||
|
|
||||||
writer = None
|
writer = None
|
||||||
|
print("OPENING CONNECTION")
|
||||||
try:
|
try:
|
||||||
reader, writer = await asyncio.wait_for(asyncio.open_connection(machine, 1080), 5)
|
reader, writer = await asyncio.wait_for(asyncio.open_connection(machine, 1080), 5)
|
||||||
writer.write(b"MAGIC")
|
writer.write(b"MAGIC")
|
||||||
writer.write(privateKeyHash[:6])
|
writer.write(privateKeyHash[:6])
|
||||||
await asyncio.wait_for(writer.drain(), 5)
|
await asyncio.wait_for(writer.drain(), 5)
|
||||||
while asyncio.get_event_loop().is_running():
|
while asyncio.get_event_loop().is_running():
|
||||||
|
print(datetime.datetime.now(), "READING REQUEST")
|
||||||
obj = await readJson(reader)
|
obj = await readJson(reader)
|
||||||
if not obj: continue
|
if not obj: continue
|
||||||
if "id" not in obj:
|
if "id" not in obj:
|
||||||
print("Invoice update?", obj)
|
print("Invoice update?", obj)
|
||||||
for i in self.subscribers: i(obj)
|
for i in self.subscribers: i(obj)
|
||||||
continue
|
continue
|
||||||
|
print(datetime.datetime.now(), "making reply")
|
||||||
await asyncio.wait_for(readReqAndReply(obj, writer, netAndWalLock), 10)
|
await asyncio.wait_for(readReqAndReply(obj, writer, netAndWalLock), 10)
|
||||||
except:
|
except:
|
||||||
traceback.print_exc()
|
traceback.print_exc()
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user