…does it mean that one app can run across multiple CPUs? Without the app knowing?!!
The sdk site has some well-honed explanations of them, this page is a good start: https://sdk.dfinity.org/docs/developers-guide/introduction-key-concepts.html
Essentially, canisters are what you deploy your app or service as.
In terms of files: When you’re building a project you’ll have a few things to deploy together, like the compiled code and any static assets, along with automatically generated data like an interface description. A canister is a bundle of all of this.
But a more useful/general way to think about them is that they contain code with an actor, which has public methods. If you’re building an app then the frontend web interface can call these methods. Or service canisters can communicate with each other directly by calling each other’s methods.
So the whole Internet Computer contains a huge number of these app and service canisters, serving frontend interfaces and/or communicating with each other.
OK, but you didn’t answer my questions above, though
Hi @groovee not part of the team but I think this article does a really good job:
Fair point. There are maybe a couple of ways to answer that:
One app’s data will be stored on and retrievable from multiple machines/replicas on the network, related to consensus needs and also allowing faster serving similar the way traditional content delivery networks do.
Concurrent calls can be served for queries (non state changing), with update calls interleaved if they make inter-canister calls, as per the article Gabriel linked above.
Within a call, it doesn’t currently run executions on multiple cores as in multi-threading, which arguably could be hidden from the developer too. There was a great post on this by Nick here actually: The future: Deterministic parallelism within a canister? (i.e. multi-core and many-core canisters)
Is it accurate to say the canister contains the code and the actor contains the state?
The actor’s state can only be updated by a single thread at a time across the whole world? And each of those updates will take a few seconds to reach global consensus?
Looking at the counter tutorial as an example of mutable state, it seems to create a single global counter. But, one counter for the whole internet isn’t very useful.
Is there a way to create multiple actors and have requests routed to the right actor?
The canister is an actor, e.g. when it processes update calls. And yes, it’s possible to fork canisters. I can only recommend you to read the article mentionend above
OK, the canister contains the code and the state and the actor.
So in the counter example, if you wanted multiple counters that can tick in parallel then the app is responsible for forking off multiple canisters itself. Since you can apparently choose the canister name yourself, you could use that to route requests to the right place.
One VM per integer counter seems inefficient but perhaps you have a plan.
If you just wanted something like a counter per user, for example, you don’t need multiple canisters. You could store counters for all users within a single canister/actor. Unless you’re reaching for something else here?
Map the user to their counter state by using the caller’s principal as a key in a key-value store, and the value is the current count.
Yep, but that seems to mean one user can be updating their counter at a time, and the total update rate is one per ~2 seconds across all users?