Get the Type of an actor createed by an actor class

I am trying to instantiate an canister from its id:

actor {
    public func main(canisterId: Text) : async Nat {
        let canister2 = actor(canisterId): **actor { getValue: () -> async Nat };**
        return await canister2.getValue();
    };
};

However, in my case I have defined the actor using an actor class, so am not sure how to declare the type signature. Anyway to get the type signature of the actor from the actor class?

In my case the asterisked code should be changed.

Cheers

A class declaration declares both a function (the constructor) and a type of the same name, so you can use name of the class directly as a type.

Have you declared a class something like:

actor class Service () { public func getValue() : async Nat {...} }

then you can replace your ** … ** by Service (or Lib.Service if defined in an imported library called Lib).

Your inline description should actually work fine (but perhaps needs some extra parenthesis).

2 Likes

Thanks Claudio, tried something similar and it worked.

If would be great to be able to have a language level feature allowing me to reference the async future type of an actor API, or to provide a default value for it while I’m waiting

For example, let’s say the actor API looks like this:

actor {
  public func callMe() : Text { "hello" };
};

Then in my code I’d like to reference the type of it’s future and provide a default.

import "SomeActor";

...
func referenceActorFutureType() : async () {
  // This is not possible, but having some way to do this would be great
  var someActorCallMeFuture : SomeActor<callMe> = async "default";
}

This comes into play when I want to make 4-5 different calls at the same time, but I want those calls to be conditional, such that I could send out anywhere from 0 to 5 calls at a time depending on various conditions.

Most of the time I’ll only need to make 1 asynchronous call, so for various reasons I don’t want to make unnecessary calls to other actors. I’d like to be able to make these calls at the same time without I also need to be able to assign each of these conditional futures, such that I am then later on able to await and collect their responses.

@claudio are there any tricks that could help me out here?

Was able to get around this with variants. Still quite a bit of repetitive code, but it works in terms of conditional parallelization :sweat_smile:

Curious if anyone has a better solution

module {
  func getCanisterStatuses(
    actor1 : Actor1,
    actor2 : Actor2,
    actor3 : Actor3,
    //...
  ) : async* {
    r1Result : Result.Result<[R1], Text>;
    r2Result : Result.Result<[R2], Text>;
    r3Result : Result.Result<[R3], Text>;
    //...
  } {

    let r1Future = if (<some r1 condition>) { #run(r1.call() } else { #skip };
    let r2Future = if (<some r2 condition>) { #run(r2.call() } else { #skip };
    let r3Future = if (<some r3 condition>) { #run(r3.call() } else { #skip };
    //...

    let r1Result = switch(r1Future) {
      case (#skip) #ok([]);
      case (#run(future)) {
        try { await future } catch (e) { #err("error in r1.call()" # Error.message(e)) };
      }
    };

    let r2Result = switch(r2Future) {
      case (#skip) #ok([]);
      case (#run(future)) {
        try { await future } catch (e) { #err("error in r2.call()" # Error.message(e)) };
      }
    };

    let r3Result = switch(r1Future) {
      case (#skip) #ok([]);
      case (#run(future)) {
        try { await future } catch (e) { #err("error in r3.call()" # Error.message(e)) };
      }
    };

    //...

    {
      r1Result;
      r2Result;
      r3Result;
      //...
    };
  };