Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Actors. #129

Merged
merged 26 commits into from Oct 22, 2022
Merged

Actors. #129

merged 26 commits into from Oct 22, 2022

Conversation

matthewhammer
Copy link
Contributor

@matthewhammer matthewhammer commented Oct 16, 2022

Continues #126, implementing Actors.

This test demonstrates how to reproduce the following steps, all of which now work:

  1. agent creates a local actor, with a name Counter.
  2. agent sends a local actor Counter a message (calling a method)
  3. Counter's methods execute with its internal state, and variables.
  4. When each method completes, it responds to the agent, which resumes control.
  5. agent upgrades actor Counter by re-using the same name later in the script (proof of concept form of upgrade, for unit testing here)
  6. the upgrade "works correctly," in the sense that:
    1. the new method definitions run now, and the old ones are replaced.
    2. the store retains its variable's values from before, after the upgrade.
actor Counter = {
  var x = 0;
  public func get() /*: async Nat*/ { x };
  public func inc() { x := x + 1 };
};
assert (Counter.get() == 0);
Counter.inc();
assert (Counter.get() == 1);
actor Counter {
  var x = 0;
  public func get() /*: async Nat*/ { x };
  public func inc() { x := x + 2 };
};
assert (Counter.get() == 1);
Counter.inc();
assert (Counter.get() == 3);
#ok

@github-actions
Copy link

Benchmark for c5d627a

Click to view benchmark
Test Base PR %
Examples/Basic example 686.3±36.72µs 662.5±38.77µs -3.47%

@github-actions
Copy link

Benchmark for 0d901c6

Click to view benchmark
Test Base PR %
Examples/Basic example 842.1±49.03µs 885.6±47.07µs +5.17%

@github-actions
Copy link

Benchmark for 21ca0b3

Click to view benchmark
Test Base PR %
Examples/Basic example 677.1±7.57µs 683.5±8.52µs +0.95%

@github-actions
Copy link

Benchmark for 12861fd

Click to view benchmark
Test Base PR %
Examples/Basic example 683.3±7.52µs 663.4±6.70µs -2.91%

fn counts<'a>(&'a mut self) -> &'a mut Counts;

fn alloc(&mut self, value: impl Into<Value_>) -> Pointer {
self.store().alloc(value)
}

fn create(&mut self, _name: Option<Id>, _actor: Actor) -> Result<Value_, Interruption> {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Create an actor (value) and add it to the VM...

To be useful for Motoko Dev Sever, maybe it should accept a string (read from a file by the caller) and some other stuff, including the canister ID that dfx knows about?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

BTW -- the name create is somewhat arbitrary, but has two nice properties now:

  • separate verb from alloc, to distinguish it from that case.
  • same verb as the IC reference spec, for the act of "creating a canister."

Done(Value_),
Interruption(Interruption),
}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Signal was going to grow to capture errors from I/O.

Except now with the Motoko Dev Server, I am now expecting network I/O to happen outside of the VM, and for this traffic to selectively affect the VM from its public API for Core, which will grow to accommodate the Dev Server.

Accordingly, I am dropping the Signal concept here, and related code.

@matthewhammer matthewhammer marked this pull request as ready for review October 22, 2022 22:13
@github-actions
Copy link

Benchmark for ee484b9

Click to view benchmark
Test Base PR %
Examples/Basic example 656.6±6.78µs 743.7±7.62µs +13.27%

@matthewhammer matthewhammer merged commit c550847 into main Oct 22, 2022
@matthewhammer matthewhammer deleted the actors branch October 22, 2022 22:30
pub enum ActorId {
/// Actor is identified by a local name in the Agent program that creates it.
Local(Id),
// to do -- case: canister ID and canister alias pair from dfx.json.
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@rvanasa ActorId could have a variant called DfxCanister or whatever name seems appropriate given what identifier you choose to use.

As you've suggested previously, perhaps it's simplest to just use the "canister alias" dfx concept that we've discussed many times now as the identifier for the DfxCanister case of ActorId? (and eschew having the replica-created canister id as part of that id, e.g., as a pair.)

If so, perhaps we can instead put that extra ID info into the actor as associated data, when it's available.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

1 participant