-
Notifications
You must be signed in to change notification settings - Fork 1.7k
Conversation
dapps/src/endpoint.rs
Outdated
@@ -39,7 +40,7 @@ pub struct EndpointInfo { | |||
pub icon_url: String, | |||
} | |||
|
|||
pub type Endpoints = Arc<BTreeMap<String, Box<Endpoint>>>; | |||
pub type Endpoints = Arc<RwLock<BTreeMap<String, Box<Endpoint>>>>; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why add RwLock
if it's only read through? doesn't seem to need any lock at all
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well, the end goal is to push to the BTreeMap new dapp entries as a js developer adds. Currently you have to restart parity to get the new dapp.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Few grumbles.
dapps/Cargo.toml
Outdated
@@ -14,6 +14,7 @@ futures = "0.1" | |||
linked-hash-map = "0.3" | |||
log = "0.3" | |||
parity-dapps-glue = "1.7" | |||
parking_lot = "0.4" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
RwLock
is re-export in util
.
dapps/src/apps/mod.rs
Outdated
let mut v = Vec::new(); | ||
// accumulate the dead dapps | ||
for (k, _) in pages.read().iter() { | ||
if k == "ui" || k == "proxy" || k == WEB_PATH { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's bad, we should export a list of local filesystem dapps in all_endpoints
(for instance return Endpoints
and Vec<String>
)
dapps/src/apps/mod.rs
Outdated
if k == "ui" || k == "proxy" || k == WEB_PATH { | ||
continue; | ||
} else if new_pages.contains_key(k) != true { | ||
v.push(k.clone()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you keep the list of local endpoints the code here can be greately simplified (just let to_remove = old_local.iter().partition(|x| !new_local.contains_key(x))
)
dapps/src/apps/mod.rs
Outdated
// new dapps to be added | ||
for (k, v) in new_pages { | ||
if pages.read().contains_key(&k) != true { | ||
pages.write().insert(k, v); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You should acquire single lock at the top of the function instead of using read()/write()
on every iteration.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I must have bad luck, but the reason I used a vector and the reason I use short term locks, (and maybe this is a unique issue to parking_lot) is that if you have a read lock, the write lock will wait indefinitely for the read lock to finish before creating it's own lock. Has no one else run into this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You should only take one write()
lock at the top (you will be able to read from it as well).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it's actually a safety feature to deadlock instead of aliasing writeable pointers
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, so:
a) if the function is not too complex, it's ok to have a write lock for the time of the function
b) with a write, it can also handle reads (unless handling mutable and immutable in the same instance [.iter()])
dapps/src/apps/mod.rs
Outdated
Arc::new(RwLock::new(pages)) | ||
} | ||
|
||
pub fn refresh_local_endpoints( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
IMHO this function should be part of Endpoints
dapps/src/apps/ui.rs
Outdated
@@ -22,6 +22,7 @@ use endpoint::{Endpoint, Handler, EndpointPath}; | |||
use {address, handlers}; | |||
|
|||
/// Redirection to UI server. | |||
#[derive(Clone)] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is it needed?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Didn't clean it after playing with the code -_-
dapps/src/router.rs
Outdated
@@ -61,14 +62,16 @@ impl http::RequestMiddleware for Router { | |||
let is_head_request = *req.method() == hyper::Method::Head; | |||
|
|||
trace!(target: "dapps", "Routing request to {:?}. Details: {:?}", url, req); | |||
let refresh = self.endpoints.clone(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is it cloned here?
dapps/src/router.rs
Outdated
@@ -109,6 +112,7 @@ impl http::RequestMiddleware for Router { | |||
=> | |||
{ | |||
trace!(target: "dapps", "Resolving to 404."); | |||
refresh.unwrap().refresh_local_dapps(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
self.endpoints
can be empty so you should unwrap.
It should be just self.endpoints.as_ref().map(|endpoints| endpoints.refresh_local_dapps())
.
Even though the dapps are refreshed we should still re-try resolving the request.
Most likely a recursive call should be done here with some additional parameter preventing a refresh again.
@@ -95,6 +95,11 @@ export default class Parity { | |||
.execute('parity_dappsList'); | |||
} | |||
|
|||
dappsRefresh () { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think the RPC method (and JS code) will be useful at all if the router can auto-refresh missing dapps.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah! Thanks for the review! I'll reply when I wake up in a few hours. The JS code just ensures an instant refresh.. otherwise you have to reload the page (+R), and I don't think we should require that. It would be confusing to the end user.
So for instance, if you link a new dapp... how would JS know unless it constantly checked if there was a new one... [When pub-sub is ready, I can change it] but this is incredibly inefficient since the number of times a developer is going to add a new dapp is like... once a month at most?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, I think refreshing the page is actually ok when you add a new dapp. As you said it will happen once a month at most.
IMHO not worth supporting additional RPC method and this additional JS code.
But I don't have very strong opinion on that. Since the code is already there we can probably merge it.
The crazy thing is that the bug would only rear it's ugly head some cases.
|
Waiting for #6192 |
dapps/src/lib.rs
Outdated
.partition(|k| new_local.contains_key(&k.clone())); | ||
// remove the dead dapps | ||
for k in to_remove { | ||
let index = local.iter().position(|x| *x == k).unwrap(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
unwrap
->expect
- This makes the function quadratic and we don't really need it here. At the end of the function just replace
self.local_endpoints
withnew_local.keys().collect()
.
dapps/src/lib.rs
Outdated
} | ||
// new dapps to be added | ||
for (k, v) in new_local { | ||
if self.endpoints.read().contains_key(&k) != true { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use !<condition>
instead of comparing to bool.
dapps/src/lib.rs
Outdated
// new dapps to be added | ||
for (k, v) in new_local { | ||
if self.endpoints.read().contains_key(&k) != true { | ||
local.push(k.clone()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That will be not needed when you do:
*local = new_local.keys().collect()
dapps/src/router.rs
Outdated
@@ -110,6 +112,7 @@ impl http::RequestMiddleware for Router { | |||
=> | |||
{ | |||
trace!(target: "dapps", "Resolving to 404."); | |||
self.endpoints.as_ref().map(|endpoints| endpoints.clone().refresh_local_dapps()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It should retry resolving the dapp.
Addressing dapps-refresh grumbles from #5752
I believe |
Closes: #4194
If adding or removing a dapp, this will update the list upon:
If you want to quickly test it:
git clone https://github.com/paritytech/skeleton mydapp
git cd mydapp
ln -s $PWD/dist $HOME/Library/Application\ Support/io.parity.ethereum/dapps/mydapp
(If you are using windows go to the tutorial... :P)
Click refresh
and to test removal:
cd ~/Library/Application Support/io.parity.ethereum/dapps
or
cd /Users/$USER/Library/Application Support/io.parity.ethereum/dapps
rm -rf mydapp