I’ve been playing with actor classes and mainly creating canisters on the fly for storage (cdn).
So basically I want to create a mini big map ish storage solution. I can create as many canisters as I want on the fly but my question is how do I set a canister compute allocation and memory allocation from motoko?
In dfx I can use
-c, --compute-allocation <compute-allocation> Specifies the canister's compute allocation. This should be a percent in the range [0..100]
and --memory-allocation <memory-allocation> Specifies how much memory the canister is allowed to use in total. This should be a value in the range [0..256 TB]
but can’t seem to find a way to do it in code. Any help would be appreciated.
You should be able to call the management canister aaaaa-aa from your deployed canister in order to update the settings
public type CanisterSettings = {
controller : ?Principal;
compute_allocation : ?Nat;
memory_allocation : ?Nat;
freezing_threshold : ?Nat;
}
public type IC0 = actor {
update_settings : {canister_id : Principal; settings : CanisterSettings} -> async ();
};
Your canister will need to have its controller set to itself for this to work however. I could have swore canisters supported upto ten controllers , but the interface says otherwise.
When your create the canister, you are specifying its controller to be owner, but when you call canister_status, the caller is actually the canister that calls create_canister and canister_status. This may not be the same as owner (how is owner defined? I can’t tell from the code.)
At least I think that is what is happening. Please do correct me if I’m wrong.
(Instead of screenshots, you could also use a GitHub gist to share files.)
Unfortunately it errors on create_canister and it’s doesn’t get to canister_status. So that’s all the code I have .
Basically I have a container and I want to automatically create as many bucket canisters and change the memory_allocation to max as the only purpose of a bucket is storage only and unfortunately I can’t do that with an actor class yet as you said above.
So rwlgt-iiaaa-aaaaa-aaaaa-cai is my canister wallet and if you look down on results you can see that the container canister controller is the same one. Also from debug on create_canister I pass owner which is [Canister ryjl3-tyaaa-aaaaa-aaaba-cai] "owner" [Canister ryjl3-tyaaa-aaaaa-aaaba-cai] rwlgt-iiaaa-aaaaa-aaaaa-cai
The controller field is now called controllers and takes a vec (Motoko immutable array) of values. So I expect the call is failing because the interface of “aaaa-aa” is incorrectly asserted and the type of the argument pass by Motoko to the IC management canister is actually incorrect in this code, causing the call to create_canister to fail.
c.f.
and note the type of canister_settings and definite_settings:
memory_allocation ( nat ) Must be a number between 0 and 2^48 (i.e 256TB). Not sure I get how it can it be 256TB, shouldn’t that be the max canister memory as in 4GB?
Also from the 4GB is it true only 2GB can be used? I got that from your comment: Note that Motoko currently uses a 2-space copying collector so the heap will be at most half the memory, and the heap is thus bounded by 2GB Note the only purpose for this canister is storage so I’m trying the make the most of it.
public func discard(a : actor) : async () { I tried this but got an error, can you pass an actor as a parameter?
The spec is too liberal and the replica will either fail or ignore requests above 4GB, I believe.
Motoko has a new compacting gc that you can select to access more than 2 GB, but it might not let you do that yet in practice because the cost of collecting all that memory is too high for a single message. GC needs to be made incremental too. We are working on that.
Your ‘discard’ function had a typo. The empty actor type is ‘actor {}’, not ‘actor’.