Use only ancestors rpc for squeak page (#1118)

* Got squeak page working without get squeak entry rpc, no streaming yet

* Implement subscribe ancestors

* Got subscribe ancestors working in frontend with download squeak click

* Delete old comments

* Update frontend build

* Remove old log lines
This commit is contained in:
Jonathan Zernik 2021-08-30 20:08:37 -07:00 committed by GitHub
parent 2934435a1d
commit e2933784ac
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
16 changed files with 132 additions and 35 deletions

View file

@ -1,4 +1,4 @@
import React, { useState, useEffect } from 'react';
import React, { useState, useEffect, useMemo } from 'react';
import { useParams, useHistory } from 'react-router-dom';
import {
Grid,
@ -29,6 +29,7 @@ import {
getNetworkRequest,
downloadRepliesRequest,
subscribeReplySqueakDisplaysRequest,
subscribeAncestorSqueakDisplaysRequest,
} from '../../squeakclient/requests';
import {
goToSqueakAddressPage,
@ -38,23 +39,16 @@ export default function SqueakPage() {
const classes = useStyles();
const history = useHistory();
const { hash } = useParams();
const [squeak, setSqueak] = useState(null);
const [ancestorSqueaks, setAncestorSqueaks] = useState([]);
const [replySqueaks, setReplySqueaks] = useState([]);
const [network, setNetwork] = useState('');
const getSqueak = (hash) => {
getSqueakDisplayRequest(hash, setSqueak);
};
const subscribeSqueak = (hash) => {
return subscribeSqueakDisplayRequest(hash, (squeak) => {
setSqueak(squeak);
setAncestorSqueaks([squeak]);
});
};
const getAncestorSqueaks = (hash) => {
getAncestorSqueakDisplaysRequest(hash, setAncestorSqueaks);
};
const subscribeAncestorSqueaks = (hash) => {
return subscribeAncestorSqueakDisplaysRequest(hash, setAncestorSqueaks);
};
const getReplySqueaks = (hash) => {
getReplySqueakDisplaysRequest(hash, setReplySqueaks);
};
@ -70,7 +64,7 @@ export default function SqueakPage() {
};
const getCurrentSqueak = () => {
getSqueak(hash);
getAncestorSqueaks(hash);
};
const onDownloadRepliesClick = (event) => {
@ -81,16 +75,23 @@ export default function SqueakPage() {
});
};
useEffect(() => {
getSqueak(hash);
}, [hash]);
useEffect(() => {
const stream = subscribeSqueak(hash);
return () => stream.cancel();
}, [hash]);
const calculateCurrentSqueak = (ancestorSqueaks) => {
if (ancestorSqueaks == null) {
return null;
} else if (ancestorSqueaks.length == 0) {
return null;
} else {
return ancestorSqueaks.slice(-1)[0];
}
}
useEffect(() => {
getAncestorSqueaks(hash);
}, [hash]);
useEffect(() => {
const stream = subscribeAncestorSqueaks(hash);
return () => stream.cancel();
}, [hash]);
useEffect(() => {
getReplySqueaks(hash);
}, [hash]);
@ -102,6 +103,8 @@ export default function SqueakPage() {
getNetwork();
}, []);
const currentSqueak = useMemo(() => calculateCurrentSqueak(ancestorSqueaks), [ancestorSqueaks]);
function NoSqueakContent() {
return (
<div>
@ -141,7 +144,7 @@ export default function SqueakPage() {
return (
<SqueakDetailItem
hash={hash}
squeak={squeak}
squeak={currentSqueak}
reloadSqueak={getCurrentSqueak}
network={network}
/>

View file

@ -68,6 +68,7 @@ import {
SubscribeBuyOffersRequest,
SubscribeReplySqueakDisplaysRequest,
SubscribeAddressSqueakDisplaysRequest,
SubscribeAncestorSqueakDisplaysRequest,
} from '../proto/squeak_admin_pb';
import { SqueakAdminClient } from '../proto/squeak_admin_grpc_web_pb';
@ -692,3 +693,21 @@ export function subscribeAddressSqueakDisplaysRequest(address, handleResponse) {
console.log(stream);
return stream;
}
export function subscribeAncestorSqueakDisplaysRequest(hash, handleResponse) {
const request = new SubscribeAncestorSqueakDisplaysRequest();
request.setSqueakHash(hash);
const stream = client.subscribeAncestorSqueakDisplays(request);
stream.on('data', (response) => {
handleResponse(response.getSqueakDisplayEntriesList());
});
stream.on('end', (end) => {
// stream end signal
console.log(end);
alert(`Stream ended: ${end}`);
});
console.log("Stream object:");
console.log(stream);
return stream;
}

View file

@ -50,6 +50,7 @@ from tests.util import make_squeak
from tests.util import open_channel
from tests.util import open_peer_connection
from tests.util import subscribe_connected_peers
from tests.util import subscribe_squeak_ancestor_entries
from tests.util import subscribe_squeak_entry
from tests.util import subscribe_squeaks_for_address
@ -688,7 +689,8 @@ def test_download_single_squeak(
saved_squeak_hash,
):
with subscribe_squeak_entry(other_admin_stub, saved_squeak_hash) as subscription_queue:
with subscribe_squeak_entry(other_admin_stub, saved_squeak_hash) as subscription_queue, \
subscribe_squeak_ancestor_entries(other_admin_stub, saved_squeak_hash) as ancestor_subscription_queue:
# Get the squeak display item (should be empty)
squeak_display_entry = get_squeak_display(
@ -727,10 +729,15 @@ def test_download_single_squeak(
assert len(get_buy_offers_response.offers) > 0
item = subscription_queue.get()
print("item:")
print("subscription_queue item:")
print(item)
assert item.squeak_hash == saved_squeak_hash
item = ancestor_subscription_queue.get()
print("ancestor_subscription_queue item:")
print(item)
assert item[0].squeak_hash == saved_squeak_hash
def test_download_squeaks_for_address(
admin_stub,

View file

@ -374,3 +374,23 @@ def subscribe_squeaks_for_address(node_stub, squeak_address):
).start()
yield q
subscribe_address_squeaks_response.cancel()
@contextmanager
def subscribe_squeak_ancestor_entries(node_stub, squeak_hash):
q = queue.Queue()
subscribe_squeak_ancestor_entries_response = node_stub.SubscribeAncestorSqueakDisplays(
squeak_admin_pb2.SubscribeAncestorSqueakDisplaysRequest(
squeak_hash=squeak_hash,
)
)
def enqueue_results():
for result in subscribe_squeak_ancestor_entries_response:
q.put(result.squeak_display_entries)
threading.Thread(
target=enqueue_results,
).start()
yield q
subscribe_squeak_ancestor_entries_response.cancel()

View file

@ -296,6 +296,10 @@ service SqueakAdmin {
*/
rpc SubscribeAddressSqueakDisplays (SubscribeAddressSqueakDisplaysRequest) returns (stream GetSqueakDisplayReply) {}
/** sqkadmin: `subscribeancestorsqueakdisplays`
*/
rpc SubscribeAncestorSqueakDisplays (SubscribeAncestorSqueakDisplaysRequest) returns (stream GetAncestorSqueakDisplaysReply) {}
}
message CreateSigningProfileRequest {
@ -1041,3 +1045,8 @@ message SubscribeAddressSqueakDisplaysRequest {
/// The address
string address = 1;
}
message SubscribeAncestorSqueakDisplaysRequest {
/// Hash of the squeak.
string squeak_hash = 1;
}

View file

@ -866,3 +866,25 @@ class SqueakAdminServerHandler(object):
yield squeak_admin_pb2.GetSqueakDisplayReply(
squeak_display_entry=display_message
)
def handle_subscribe_ancestor_squeak_displays(self, request, stopped):
squeak_hash_str = request.squeak_hash
squeak_hash = bytes.fromhex(squeak_hash_str)
logger.info(
"Handle subscribe ancestor squeak displays for hash: {}".format(squeak_hash_str))
squeak_entries_stream = self.squeak_controller.subscribe_squeak_ancestor_entries(
squeak_hash,
stopped,
)
for squeak_entries in squeak_entries_stream:
logger.info(
"Got number of ancestor squeak entries: {}".format(
len(squeak_entries)
)
)
squeak_display_msgs = [
squeak_entry_to_message(entry) for entry in squeak_entries
]
yield squeak_admin_pb2.GetAncestorSqueakDisplaysReply(
squeak_display_entries=squeak_display_msgs
)

View file

@ -41,7 +41,7 @@ class SqueakAdminServerServicer(squeak_admin_pb2_grpc.SqueakAdminServicer):
self.server = None
def start(self):
self.server = grpc.server(futures.ThreadPoolExecutor(max_workers=10))
self.server = grpc.server(futures.ThreadPoolExecutor(max_workers=100))
squeak_admin_pb2_grpc.add_SqueakAdminServicer_to_server(
self, self.server)
self.server.add_insecure_port("{}:{}".format(self.host, self.port))
@ -339,3 +339,15 @@ class SqueakAdminServerServicer(squeak_admin_pb2_grpc.SqueakAdminServicer):
request,
stopped,
)
def SubscribeAncestorSqueakDisplays(self, request, context):
stopped = threading.Event()
def on_rpc_done():
logger.info("Stopping SubscribeAncestorSqueakDisplays.")
stopped.set()
context.add_callback(on_rpc_done)
return self.handler.handle_subscribe_ancestor_squeak_displays(
request,
stopped,
)

View file

@ -1,14 +1,14 @@
{
"files": {
"main.js": "/static/js/main.7a5a1e9d.chunk.js",
"main.js.map": "/static/js/main.7a5a1e9d.chunk.js.map",
"main.js": "/static/js/main.06f284fc.chunk.js",
"main.js.map": "/static/js/main.06f284fc.chunk.js.map",
"runtime-main.js": "/static/js/runtime-main.9f0ba400.js",
"runtime-main.js.map": "/static/js/runtime-main.9f0ba400.js.map",
"static/css/2.ea4ba2f0.chunk.css": "/static/css/2.ea4ba2f0.chunk.css",
"static/js/2.9773e69b.chunk.js": "/static/js/2.9773e69b.chunk.js",
"static/js/2.9773e69b.chunk.js.map": "/static/js/2.9773e69b.chunk.js.map",
"index.html": "/index.html",
"precache-manifest.64861491e22f3dc094822bd9a09ecbe0.js": "/precache-manifest.64861491e22f3dc094822bd9a09ecbe0.js",
"precache-manifest.9c4e0e75e76ff8048a53c6287bba9636.js": "/precache-manifest.9c4e0e75e76ff8048a53c6287bba9636.js",
"service-worker.js": "/service-worker.js",
"static/css/2.ea4ba2f0.chunk.css.map": "/static/css/2.ea4ba2f0.chunk.css.map",
"static/js/2.9773e69b.chunk.js.LICENSE.txt": "/static/js/2.9773e69b.chunk.js.LICENSE.txt",
@ -20,6 +20,6 @@
"static/js/runtime-main.9f0ba400.js",
"static/css/2.ea4ba2f0.chunk.css",
"static/js/2.9773e69b.chunk.js",
"static/js/main.7a5a1e9d.chunk.js"
"static/js/main.06f284fc.chunk.js"
]
}

View file

@ -1 +1 @@
<!doctype html><html lang="en"><head><meta charset="utf-8"/><link rel="shortcut icon" href="/favicon.ico"/><meta name="viewport" content="width=device-width,initial-scale=1,shrink-to-fit=no"/><meta name="theme-color" content="#000000"/><link rel="manifest" href="/manifest.json"/><title>Squeak Node</title><meta name="description" content="Squeak Node is a frontend for accessing a squeak node"><meta name="keywords" content="squeak, bitcoin, lightning"><meta name="author" content="Flatlogic LLC."><link href="/static/css/2.ea4ba2f0.chunk.css" rel="stylesheet"></head><body style="font-family:Roboto,sans-serif"><noscript>You need to enable JavaScript to run this app.</noscript><div id="root"></div><script>!function(e){function r(r){for(var n,f,l=r[0],a=r[1],i=r[2],c=0,s=[];c<l.length;c++)f=l[c],Object.prototype.hasOwnProperty.call(o,f)&&o[f]&&s.push(o[f][0]),o[f]=0;for(n in a)Object.prototype.hasOwnProperty.call(a,n)&&(e[n]=a[n]);for(p&&p(r);s.length;)s.shift()();return u.push.apply(u,i||[]),t()}function t(){for(var e,r=0;r<u.length;r++){for(var t=u[r],n=!0,l=1;l<t.length;l++){var a=t[l];0!==o[a]&&(n=!1)}n&&(u.splice(r--,1),e=f(f.s=t[0]))}return e}var n={},o={1:0},u=[];function f(r){if(n[r])return n[r].exports;var t=n[r]={i:r,l:!1,exports:{}};return e[r].call(t.exports,t,t.exports,f),t.l=!0,t.exports}f.m=e,f.c=n,f.d=function(e,r,t){f.o(e,r)||Object.defineProperty(e,r,{enumerable:!0,get:t})},f.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},f.t=function(e,r){if(1&r&&(e=f(e)),8&r)return e;if(4&r&&"object"==typeof e&&e&&e.__esModule)return e;var t=Object.create(null);if(f.r(t),Object.defineProperty(t,"default",{enumerable:!0,value:e}),2&r&&"string"!=typeof e)for(var n in e)f.d(t,n,function(r){return e[r]}.bind(null,n));return t},f.n=function(e){var r=e&&e.__esModule?function(){return e.default}:function(){return e};return f.d(r,"a",r),r},f.o=function(e,r){return Object.prototype.hasOwnProperty.call(e,r)},f.p="/";var l=this["webpackJsonpsqueak-node-frontend"]=this["webpackJsonpsqueak-node-frontend"]||[],a=l.push.bind(l);l.push=r,l=l.slice();for(var i=0;i<l.length;i++)r(l[i]);var p=a;t()}([])</script><script src="/static/js/2.9773e69b.chunk.js"></script><script src="/static/js/main.7a5a1e9d.chunk.js"></script></body></html>
<!doctype html><html lang="en"><head><meta charset="utf-8"/><link rel="shortcut icon" href="/favicon.ico"/><meta name="viewport" content="width=device-width,initial-scale=1,shrink-to-fit=no"/><meta name="theme-color" content="#000000"/><link rel="manifest" href="/manifest.json"/><title>Squeak Node</title><meta name="description" content="Squeak Node is a frontend for accessing a squeak node"><meta name="keywords" content="squeak, bitcoin, lightning"><meta name="author" content="Flatlogic LLC."><link href="/static/css/2.ea4ba2f0.chunk.css" rel="stylesheet"></head><body style="font-family:Roboto,sans-serif"><noscript>You need to enable JavaScript to run this app.</noscript><div id="root"></div><script>!function(e){function r(r){for(var n,f,l=r[0],a=r[1],i=r[2],c=0,s=[];c<l.length;c++)f=l[c],Object.prototype.hasOwnProperty.call(o,f)&&o[f]&&s.push(o[f][0]),o[f]=0;for(n in a)Object.prototype.hasOwnProperty.call(a,n)&&(e[n]=a[n]);for(p&&p(r);s.length;)s.shift()();return u.push.apply(u,i||[]),t()}function t(){for(var e,r=0;r<u.length;r++){for(var t=u[r],n=!0,l=1;l<t.length;l++){var a=t[l];0!==o[a]&&(n=!1)}n&&(u.splice(r--,1),e=f(f.s=t[0]))}return e}var n={},o={1:0},u=[];function f(r){if(n[r])return n[r].exports;var t=n[r]={i:r,l:!1,exports:{}};return e[r].call(t.exports,t,t.exports,f),t.l=!0,t.exports}f.m=e,f.c=n,f.d=function(e,r,t){f.o(e,r)||Object.defineProperty(e,r,{enumerable:!0,get:t})},f.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},f.t=function(e,r){if(1&r&&(e=f(e)),8&r)return e;if(4&r&&"object"==typeof e&&e&&e.__esModule)return e;var t=Object.create(null);if(f.r(t),Object.defineProperty(t,"default",{enumerable:!0,value:e}),2&r&&"string"!=typeof e)for(var n in e)f.d(t,n,function(r){return e[r]}.bind(null,n));return t},f.n=function(e){var r=e&&e.__esModule?function(){return e.default}:function(){return e};return f.d(r,"a",r),r},f.o=function(e,r){return Object.prototype.hasOwnProperty.call(e,r)},f.p="/";var l=this["webpackJsonpsqueak-node-frontend"]=this["webpackJsonpsqueak-node-frontend"]||[],a=l.push.bind(l);l.push=r,l=l.slice();for(var i=0;i<l.length;i++)r(l[i]);var p=a;t()}([])</script><script src="/static/js/2.9773e69b.chunk.js"></script><script src="/static/js/main.06f284fc.chunk.js"></script></body></html>

View file

@ -1,6 +1,6 @@
self.__precacheManifest = (self.__precacheManifest || []).concat([
{
"revision": "46fb5dbc7ee74e3dbaa877f13de0cc97",
"revision": "2449b8de898a407e8bb665bfeab5d25d",
"url": "/index.html"
},
{
@ -16,8 +16,8 @@ self.__precacheManifest = (self.__precacheManifest || []).concat([
"url": "/static/js/2.9773e69b.chunk.js.LICENSE.txt"
},
{
"revision": "e72da439f753d658c74d",
"url": "/static/js/main.7a5a1e9d.chunk.js"
"revision": "c4b903fdf0a7f13e8522",
"url": "/static/js/main.06f284fc.chunk.js"
},
{
"revision": "cc9816de5a8639d377ea",

View file

@ -14,7 +14,7 @@
importScripts("https://storage.googleapis.com/workbox-cdn/releases/4.3.1/workbox-sw.js");
importScripts(
"/precache-manifest.64861491e22f3dc094822bd9a09ecbe0.js"
"/precache-manifest.9c4e0e75e76ff8048a53c6287bba9636.js"
);
self.addEventListener('message', (event) => {

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -705,3 +705,8 @@ class SqueakController:
if squeak_address == str(item.GetAddress()):
squeak_hash = get_hash(item)
yield self.get_squeak_entry(squeak_hash)
def subscribe_squeak_ancestor_entries(self, squeak_hash: bytes, stopped: threading.Event):
for item in self.new_squeak_listener.yield_items(stopped):
if squeak_hash == get_hash(item):
yield self.get_ancestor_squeak_entries(squeak_hash)