Define state consistency within a revision#223
Conversation
c0189ab to
1919a88
Compare
aef6d2c to
4dfb658
Compare
Codecov Report
@@ Coverage Diff @@
## main #223 +/- ##
==========================================
- Coverage 27.78% 27.24% -0.55%
==========================================
Files 50 50
Lines 11886 11729 -157
Branches 6634 6564 -70
==========================================
- Hits 3303 3195 -108
- Misses 6391 6446 +55
+ Partials 2192 2088 -104
Continue to review full report at Codecov.
|
b368d34 to
6febf59
Compare
anp
left a comment
There was a problem hiding this comment.
Sorry it took so long to get to this! I like this approach a lot, although I have some questions about the public API it exposes -- see my review comments.
| { | ||
| // RunLoop always forces it's first revision? | ||
| // or maybe just check if current revision is 0 | ||
| self.force(); |
There was a problem hiding this comment.
If it's possible to remove the force() API, I'd prefer that. It's an additional branch at the top of each revision but I don't think this code isn't hot enough to care about that overhead.
| /// Runs the root closure once with access to the runtime context, returning | ||
| /// the result. `Waker` is set for the next `Revision`, which starts after | ||
| /// the start of the run. | ||
| pub fn run_once_with(&mut self, waker: Waker) -> Out { |
There was a problem hiding this comment.
Is it possible to make this the only API? Is there a reason we still need to cache the waker and support running without one?
| /// call `Runtime::run_once` on a regular interval regardless. | ||
| pub fn set_state_change_waker(&mut self, wk: Waker) { | ||
| self.wk = wk; | ||
| pub fn set_state_change_waker(&mut self, waker: Waker) { |
There was a problem hiding this comment.
At one point we discussed removing this altogether in favor of deleting run_once and having run_once_with take a waker -- is that still an option here?
| rcs_write.revision.0 += 1; | ||
| rcs_write.pending_changes.store(false, std::sync::atomic::Ordering::Relaxed); | ||
| drop(rcs_write); |
There was a problem hiding this comment.
Could you extract this to a separate method like RevisionController::increment_revision? It'll make calls to execute() a little more verbose but we'll never risk blocking writes to state variables if something changes here, because the write guard can't escape the controller's method body.
| } | ||
|
|
||
| #[derive(Debug)] | ||
| pub(crate) struct RevisionControlSystem { |
There was a problem hiding this comment.
nit: RevisionController
Can you move this type to another file, src/runtime/controller.rs?
| let rcs_read = self.rcs.read(); | ||
| let current = rcs_read.revision; |
There was a problem hiding this comment.
| let rcs_read = self.rcs.read(); | |
| let current = rcs_read.revision; | |
| let current = rcs.revision(); |
|
|
||
| /// Returns a reference to the current commit. | ||
| pub fn current_commit(&mut self) -> &Commit<State> { | ||
| let current = self.rcs.read().revision; |
There was a problem hiding this comment.
| let current = self.rcs.read().revision; | |
| let current = self.rcs.revision(); |
| <li> | ||
| <a style="cursor: pointer;" | ||
| class={if *visibility == to_set { "selected" } else { "" }} | ||
| class={if *visibility.commit_at_root() == to_set { "selected" } else { "" }} |
There was a problem hiding this comment.
We shouldn't need to acquire a lock here to get the visibility for the revision, but I think this is a problem for you because of my past laziness.
At the top of this function is this attribute:
#[illicit::from_env(visibility: &Key<Visibility>)]
I think this needs to become
#[illicit::from_env(visibility: &Commit<Visibility>, set_visibility: &Key<Visibility>)]
Which will require exposing the current commit via https://github.com/anp/moxie/blob/main/dom/examples/todo/src/lib.rs#L53 as well.
| crate::App::boot_fn(&[Todo::new("weeeee")], root.clone(), || { | ||
| let todo = &illicit::expect::<Key<Vec<Todo>>>()[0]; | ||
| let todos_key = &illicit::expect::<Key<Vec<Todo>>>(); | ||
| let todo = &todos_key.commit_at_root()[0]; |
There was a problem hiding this comment.
Similarly to my other comment, I think we need to pass down a Commit<Vec<Todo>> from the App.
| @@ -35,8 +35,8 @@ pub fn toggle(default_checked: bool) -> Span { | |||
| #[illicit::from_env(todos: &Key<Vec<Todo>>, visibility: &Key<Visibility>)] | |||
| pub fn todo_list() -> Ul { | |||
There was a problem hiding this comment.
See my comments in other todomvc files, I think if you add Commit<Visibility> and Commit<Vec<Todo>> to the illicit environment then you can avoid all the commit_at_root calls in this file.
|
A question: would this change be easier if |
Removed `commit_at_root` field of the `Key` bc of it being out of date.
increments, commits from the past revisions are lazely commited at first measurement
6febf59 to
cfa7bec
Compare
Resolves #222 #220 #215 #197.