-
Notifications
You must be signed in to change notification settings - Fork 0
Core Semantics
These rules give the behavior of Rambla in V1. The rules are frozen. The generators and all the adapters use them. Thus a change to one rule is a breaking change. Tests examine each rule.
The primary source is
SEMANTICS.md.
This page is a summary in Simplified Technical English.
If a PropertyChanged subscriber makes an error, Rambla does not catch the error.
The error goes to the caller.
Rambla always keeps the state operational. Before it raises the notifications, Rambla clears the flush flag and empties the set of dirty properties. Thus a subsequent mutation makes a new flush. The notifications after the error do not occur in that flush. The values are already in the fields.
The same rule applies to the scheduler. If Post makes an error, Rambla removes
the flush flag. Thus a subsequent mutation posts a new flush.
In one flush, the order of the PropertyChanged events is not specified. Rambla
notifies each dirty property one time. Do not write code that needs Bid before
Ask.
SetField compares the two values with EqualityComparer<T>.Default. If the
values are equal, Rambla does these operations:
- It does not write the field.
- It does not mark the property.
- It does not raise a notification.
- It does not count a mutation.
Thus StateMetrics.Mutations counts the true changes, not the write attempts.
- The disposal of the external scope of
BeginUpdate()makes exactly one flush. If no value changed in the batch, it makes no flush. - With nested batches, only the external scope makes the flush.
- You can dispose the scopes in any order.
- A second disposal of one scope has no result.
- No flush occurs while a batch is open.
IStateScheduler.Post can run the flush immediately or later. Rambla is correct
in both conditions. Rambla posts the flush outside of its lock. Thus an immediate
scheduler does not raise a notification while the lock is closed.
RamblaState holds no resources. It is not IDisposable. It does not dispose
its scheduler. The caller holds the scheduler and disposes it.
A property getter reads the field with no synchronization. Thus a reader on a
different thread can get an old value. For a type that is longer than one machine
word, such as decimal, the reader can get a mixture of the old bytes and the new
bytes.
A read in a PropertyChanged handler is always safe. To read a long value safely
from a different thread, publish an immutable object.
The two collections obey the rules above and these additional rules.
- A read gives the visible contents. The visible contents always agree with the notifications that Rambla raised. A mutation is not visible before the next flush.
-
One flush raises the minimum number of notifications. The flush compares
the previous contents with the pending target. If more than
ResetThresholditems changed, the flush raises oneResetnotification. The default value is 32. -
V1 has no
Movenotification. A change of the order givesReplacenotifications. - The mutators accept any thread. The reads and the notifications belong to the thread of the scheduler.
- Only one flush operates at a time. A flush that finds a flush in operation stops. The flush in operation applies all the changes.
- An error in a handler does not leave a partial condition. The flush stops and the error goes to the caller. Then Rambla makes one recovery flush. That flush makes the contents agree with the notifications.
The dictionary adds the insertion order, one Replace for each key, mutators that
use the pending target, and an atomic ReplaceSnapshot. Refer to
Collections.
-
One run at a time. By default,
CanExecutegivesfalsewhile a run is in operation. WithCancelPrevious, a new run cancels the run in operation. -
A cancelled run cannot change the state. Only the last run gives a value
to
IsRunningand to the error property. - The command holds the error. The error does not go to the caller. The command deletes the error when the next run starts.
-
Cancellation is not an error. The error property stays
null. -
The run continues on the thread that started it. Thus a command that a
person starts from the UI thread gives its state on the UI thread, for all
schedulers.
CanExecuteChangedalso goes through the scheduler, and Rambla coalesces it. - Rambla makes the command at the first read of the command property.
- The command holds no resources between the runs. A run that is in operation continues after the view closes. Cancel it if this is not correct for your application.
- The rate is a maximum, not a target.
- The scheduler releases the first post after an idle interval immediately.
- The scheduler does not discard a flush.
- An error in a subscriber does not stop the flushes behind it.
- The scheduler holds a timer. The caller disposes the scheduler.
Refer to Schedulers.
Rambla — state for real-time .NET desktop applications · MIT · github.com/nicoseijas/Rambla · This wiki follows ASD-STE100.
Use Rambla
Reference