Extremely scalable cloud applications made easy using the Azure service fabric actor model
This is a modal window.
The media could not be loaded, either because the server or network failed or because the format is not supported.
Formal Metadata
Title |
| |
Title of Series | ||
Number of Parts | 163 | |
Author | ||
License | CC Attribution - NonCommercial - ShareAlike 3.0 Unported: You are free to use, adapt and copy, distribute and transmit the work or content in adapted or unchanged form for any legal and non-commercial purpose as long as the work is attributed to the author in the manner specified by the author or licensor and the work or content is shared also in adapted form only under the conditions of this | |
Identifiers | 10.5446/50240 (DOI) | |
Publisher | ||
Release Date | ||
Language |
Content Metadata
Subject Area | ||
Genre | ||
Abstract |
|
00:00
ModemLogicCodeConfiguration spaceSoftware frameworkFormal languageWeb servicePoint cloudTwitterScaling (geometry)BuildingMobile WebCartesian coordinate systemWeb serviceComplex (psychology)Multiplication signRight angleVirtual machineFunctional (mathematics)Data structureVideo gameTerm (mathematics)AbstractionTelecommunicationSocial classInternet service providerConsistencyGastropod shellServer (computing)Power (physics)WindowFigurate numberMetric systemCycle (graph theory)Connectivity (graph theory)Configuration spaceCodePoint (geometry)MereologyAreaIntegrated development environmentRevision controlInformation technology consultingEnterprise architectureFormal languageNormal (geometry)Replication (computing)NumberLogicSoftware frameworkData integrityCloud computingDisplacement MappingAutonomic computingLine (geometry)ScalabilityPhysicalismSet (mathematics)Independence (probability theory)Dependent and independent variablesConstraint (mathematics)State of matter
08:28
Web serviceRun time (program lifecycle phase)Local ringState of matterInstance (computer science)ConsistencyDatabase normalizationReplication (computing)Scale (map)Partition (number theory)Software frameworkQueue (abstract data type)LogicData managementArchitectureComponent-based software engineeringMessage passingVirtual realityMessage passingProxy serverThread (computing)Mathematical modelLogicScaling (geometry)Web serviceObject modelComputing platformVirtual machineProgramming paradigmEnterprise architectureUniformer RaumProjective planeGroup actionObject (grammar)NumberDemosceneDerivation (linguistics)Database normalizationPartition (number theory)State of matterLocal ringDatabaseSequelFormal languageProcess (computing)CASE <Informatik>MultiplicationMultiplication signData dictionaryCodeGame controllerCategory of beingIndependence (probability theory)Right angleExtreme programmingInstance (computer science)Queue (abstract data type)Data storage deviceType theoryWeb 2.0Arithmetic meanPower (physics)Software framework2 (number)Physical systemPoint (geometry)AreaSingle-precision floating-point formatConnectivity (graph theory)MiniDiscData managementSet (mathematics)Run time (program lifecycle phase)Cartesian coordinate systemInternet der DingeDemo (music)Computer animation
16:57
Twin primeScripting languageMachine visionComputing platformWeb serviceProjective planeAxiom of choiceData structureCartesian coordinate systemCategory of beingTrailVirtual machineSoftware developerInterface (computing)EmulatorMultiplicationRevision controlType theoryRight angleBitState of matterPoint cloudServer (computing)NumberCodierung <Programmierung>CASE <Informatik>Web 2.0Installation artClient (computing)Configuration spaceZoom lensCodeSlide ruleEntire functionPartition (number theory)Visualization (computer graphics)XML
21:07
Hidden Markov modelPartition (number theory)Web serviceRun time (program lifecycle phase)InfinityThread (computing)outputString (computer science)Interface (computing)Task (computing)Game theoryState of matterSynchronizationElectronic mailing listReading (process)Replication (computing)Object (grammar)Information technology consultingPoint (geometry)Video game consoleCartesian coordinate systemSpeicherbereinigungProjective planeSocial classCentralizer and normalizerMultiplication signDefault (computer science)Single-precision floating-point formatField (computer science)Client (computing)Line (geometry)EstimationVolume (thermodynamics)Mechanism designReading (process)State of matterReplication (computing)Interface (computing)CodeWeb serviceWebsiteNumberWordData storage device2 (number)Local ringProxy serverMessage passingChainObject (grammar)Thread (computing)String (computer science)Sampling (statistics)Type theoryGeneric programmingInsertion lossDifferent (Kate Ryan album)ImplementationDesign by contractDirected graphConstructor (object-oriented programming)Semiconductor memoryCategory of beingMultilaterationPhysical systemDependent and independent variablesDatabase normalizationSlide ruleDemo (music)Concurrency (computer science)Read-only memoryAttribute grammarVideo gameCycle (graph theory)System callRun time (program lifecycle phase)Partition (number theory)XMLComputer animation
30:13
Context awarenessGame theoryDefault (computer science).NET FrameworkConcurrency (computer science)Coma BerenicesTask (computing)State of matterData storage deviceMathematical analysisFrequencyStatisticsInterface (computing)Event horizonOvalRandom numberProxy serverPhysical systemSystem callSocial classRow (database)Multiplication signFile archiverAsynchronous Transfer ModeObject (grammar)Context awarenessLogicDefault (computer science)Web serviceData analysisState of matterInternet der DingeConcurrency (computer science)Data storage deviceGame theoryDemo (music)Randomization2 (number)NumberGroup actionStatement (computer science)Interface (computing)CodeEvent horizonClient (computing)Point (geometry)Design by contractVideo game consoleProxy serverIntelligent NetworkField (computer science)CASE <Informatik>Internet service providerWebsiteGoodness of fitTerm (mathematics)Physical lawFrequencyImplementationMathematicsBoundary value problemComputer animation
39:18
Menu (computing)Game theoryReplication (computing)Server (computing)Partition (number theory)Web serviceConfiguration spaceMultiplication signType theoryCodeComputer animation
40:26
Web serviceGame theoryPartition (number theory)Sampling (statistics)Roundness (object)Physical systemType theoryGroup actionWritingCASE <Informatik>Numbering schemeComputer animation
42:23
Sample (statistics)Web serviceReading (process)Row (database)Sampling (statistics)Exception handlingRule of inferenceCloud computingType theoryCartesian coordinate systemGame theoryVirtual machineAsynchronous Transfer ModeDomain nameWeb 2.0Graph coloring1 (number)Event horizonComputer animation
44:58
Maxima and minimaQuicksortCartesian coordinate systemPoint (geometry)Control flowClient (computing)Revision controlTable (information)Power (physics)Multiplication signCuboidPartition (number theory)Gastropod shellRow (database)Computer animation
46:40
Sample (statistics)Partition (number theory)Slide ruleMultiplication signSet (mathematics)CuboidWhiteboardVideoconferencingComputer animation
47:47
Event horizonWeb serviceComa BerenicesMathematical modelPoint cloudOvalWeb serviceCartesian coordinate systemState of matter2 (number)Chaos (cosmogony)Boss CorporationServer (computing)WindowPoint cloudHypermediaForestLatent heatControl flowData managementBitPoint (geometry)Level (video gaming)SequelMathematical modelAreaQueue (abstract data type)Shared memoryEvent horizonTelecommunicationType theoryStatement (computer science)Multiplication signDatabaseComputing platformRevision controlBus (computing)Object modelDemo (music)Web 2.0Computer simulationComputer animation
52:11
OvalClient (computing)Event horizonDifferent (Kate Ryan album)Source codeComputer animation
Transcript: English(auto-generated)
00:01
Welcome everybody. Thanks for attending my session on Microsoft Azure Service Fabric. My name is Patrick van Dorp. I'm a lead consultant and my main expertise is cloud computing. I work for a company named Expirit and we're focused on cloud, on ALM and on enterprise mobility as well.
00:24
I've been an MVP for five years now and I'm somewhat active on Twitter as well. So if you want to stay up to speed about the Azure topic, follow me on Twitter.
00:43
So first let me just talk about some of the challenges we have building modern applications. Modern applications is like this new term, right? In our daily life, our work life exists from building in features, functional requirements.
01:04
Functional requirements that add business value for our customers. And we need to implement those features faster and faster, right? Because markets are changing faster and faster. But at the same time we need to take into account the non-functional requirements, right?
01:21
And there are a lot of non-functional requirements. If we want to deploy faster, if we want to have faster deployment cycles and release cycles of our application, we will typically choose cloud to deploy to. But cloud brings with it its own complexity.
01:41
You have to make sure that your data integrity isn't compromised. You need to be sure that you don't have a vendor lock-in. Oftentimes you want your application to run both in the cloud and on-premise. You need to take into account scalability. When should I scale? On what metrics should I scale?
02:02
And how much does that cost me? You need to take into account performance, right? We can still create bottlenecks. The more components we create, the more bottlenecks we potentially create. We need to think about our availability.
02:21
I mean, a cloud platform offers us a certain number of lines in SLA, availability. But we still need to design our applications the right way so that we can match that. And we need to know about the life cycle, right?
02:40
We need to have our deployments in place. So there's this other term, microservices, that I hear a lot these days. And microservices tend to resolve some of the issues of building big applications and deploying them to cloud environments or any other unreliable environment.
03:06
So what is a microservice? Microservices are autonomous services or components that consist both logic and state. And you can version and upgrade and deploy them separately.
03:23
A microservice should always have a single responsibility. That means that we can have smaller teams that are dedicated to one particular area of the business. So they can understand that particular area of the business better than anyone. So they can anticipate on features and thus add value to the business.
03:45
And that's what it's all about. Microservices should be easily discoverable. They should be resilient to failure. If one microservice fails, it shouldn't make all the other microservices fail.
04:01
With one big application, if one part fails, just the application fails. Typically you want to deploy your microservices in a packaged way, like a container. So you have your configuration which describes your service and the environment it runs on.
04:21
And you have your code that's running. And one of the key aspects is, because we have small teams and teams have preference in terms of frameworks and languages, and some languages are better for some purposes than others, microservices should be able to be written in various languages.
04:43
And they should be able to communicate together. That's very important. So if we look at how we used to do it, this is our monolith application. In our monolith application we had our nice layered structure, our API, our business logic, our data layer.
05:04
But the various vertical features of a business were all packed into that one application. So your team needed to know everything about every vertical in the business. With microservices you have small teams focusing on one vertical.
05:24
So they get to know that vertical very well. And each microservice still has the layered structure that we're used to. So now we're building microservices. So that's the solution to all our problems, right?
05:40
Well actually not, because we are adding more components, and more components mean more complexity. We need them to be able to discover each other. They need to communicate with each other. We need to think about replication and failover. We need to think about how many services will we host on one virtual or physical machine.
06:05
We need to think about a whole lot of things, data consistency. And that adds complexity. And once we've done that, we also want the same application, the same code to run both in Microsoft Azure as on-premises,
06:23
or perhaps other clouds, our service providers clouds, maybe AWS. I don't know, but we don't want to change our code to do so. So how do we deal with that? Microsoft came up with a new service. It's called Microsoft Azure Service Fabric.
06:42
And that abstracts all the complexity for us, and deals with all the communication and difficult stuff. So how does it work? So with Azure Service Fabric, we first deploy and configure a cluster. And a cluster is nothing more than a set of independent physical or virtual machines that run,
07:06
for now, Windows Server 2012 R2. And we can install a service fabric service host service on there. That's a mouthful.
07:21
And once we do that, we can configure the cluster on those nodes. We do that with PowerShell, and we can configure a cluster. And that lays an abstraction layer over the actual virtual machines or physical machines that we can talk to.
07:41
So once we developed our applications, and our applications are just a set of microservices that we put together, we just deploy the application to the cluster, and we let the cluster figure out where to put the individual services. And this will be done automatically based on metrics.
08:05
But we still have the flexibility to define placement constraints. So we can say this service can only be on machines that have this placement constraint. It can also be determined by metrics that we can define ourselves.
08:24
So we can say this service requires at least two gigabytes of RAM, and it will find the right node to put it on. Now what types of services can we write on top of this?
08:43
We can write actually two types of services, stateless services and stateful services. And we can host any number of other runtimes as well. For stateless services, it's important to know that they don't contain local state. And with local state, I mean something that's stored on disk.
09:05
You can compare this with how we're used to doing this within a web role. You can store things on disk, but once your service goes down or something happens with the virtual machine, your state is lost. That's the same here with stateless services.
09:24
They can, however, store their state externally, like we're used to with web roles. They can store it in SQL database, they can store it in DocumentDB or any other type of storage. But that's external storage. And the whole point of Azure Service Fabric is to keep your data close to where your code runs.
09:51
Stateless services, we can scale to improve performance. We don't need to scale it. We can have one instance of a service. And once my node goes down, it will be automatically provisioned on another node within seconds.
10:05
It's not that you have to wait like 15 minutes for it to provision. It's within seconds, it's on another node. So for redundancy, you don't necessarily need to scale. But for performance, you can scale. Stateful services, this is where it gets interesting.
10:21
Because stateful services contain highly consistent local state. And that state is located where your code is running. So whenever you load your state, you load it from the same machine. And that's very low latency. We can have redundancy through replica sets.
10:43
And we can specify how many replicas our service should have. So how many replicas of the state of our service should be there. So we can say, well, in the end, I want five replicas of my state. And I don't want to send an acknowledge back until two or three.
11:04
You can specify two or three replicas are fully replicated. So we can adjust that. We can adjust any number there. So if you want to up your redundancy, you can do that.
11:21
And we can scale by using partitions. And each partition will have the identical replica set that you specify. And a replica set consists of one primary replica. And the rest are all active secondary replicas. And so you're always talking to the primary.
11:43
And that will be replicated to the secondaries. And once the primary goes down, one of the secondaries will be promoted to primary. And with the partition, you have multiple of those setups. So you can scale for performance by using partitions.
12:01
Now as I said, you can run other runtimes as well. Other runtimes frameworks. You can actually run any existing XE that you want. This means it will migrate the process to another node when the node fails. It doesn't mean the reliability yet.
12:21
I'm certain there will be SDKs for other languages in the future, but they are not there yet. So the whole principle of the primary and the secondaries, you might have heard of that with SQL database. If you've worked with Azure SQL database, you've heard of that principle.
12:43
And that's actually, Azure SQL database is actually a service that is hosted on this technology. So this technology is not new. This technology has been around for more than five years. It's only until, I think, a year and a half ago that Microsoft decided to disclose this technology to the public.
13:06
But they found that the programming models they were using weren't too developer-friendly. So in the past year and a half, they've been working on creating those programming models for us. Now one of them is the Reliable Services API.
13:24
With the Reliable Services API, we can create microservices that are hosted on that reliant platform. And we can store our state in reliable dictionaries and reliable queues. So we can create services with very high throughput there.
13:42
And still, they are very reliable and consistent. Now you have full control over how you build your service here. You can do anything you like with it, but it also requires you to create more control logic.
14:01
And that makes your application more complex. But it is closer to what we're used to. On the other side, we have the Reliable Actors API. And that's what this talk will be about, the rest of this talk will be about. And just imagine, thinking back at the microservices. Just imagine, what if every object in my object model would have a microservice for itself to be hosted.
14:30
And it would be a distributed object model. So every object could be deployed somewhere in the cluster independently. That would be awesome, right?
14:42
So with the Reliable Actors API, the state management is done automatically. We don't have to create any reliable dictionaries or queues or anything like that. We just write to a state property and it will be stored. This can be used for extremely scalable architectures.
15:01
You can think of Halo 4. Halo 4 is based on Project Orleans. Maybe you guys heard of Project Orleans. That's also an actor-based model. And actually this is a derivative of that. But then it's hosted on this reliable platform. Another great example for using actors is in IoT.
15:25
So if every device is an actor, that will make our code very simple. We can implement the logic in one object and that object can be hosted anywhere. The only thing we have to do is monitor the cluster.
15:44
And if the cluster gets too busy, we just scale one extra or two extra nodes with it. So what is an actor? Who of you have heard of Project Orleans? Almost all of you.
16:01
So I don't have to tell you what an actor is. An actor is a grain. An actor is an isolated single-threaded component that contains both state and behavior. Actors communicate with the system and to each other using asynchronous messages. Everything is asynchronous.
16:21
And actors are virtual. You never need to construct them or destroy them. You just ask for a proxy and you get it. And if the actor was never there, it will create a new actor. If the actor was there at some point in time, it will fetch that state and that data.
16:53
So let's do a quick demo.
17:04
Okay, so when you get started with the reliable actor API, you need to download the Microsoft Azure Service Fabric SDK Preview 1, I believe it's called. You can use the web platform installer to do that.
17:22
That will install the service fabric, service host service. And it will install some PowerShell scripts. And it will install the Visual Studio tooling. And the Visual Studio tooling is like this.
17:43
I can create a new project. Why am I using my trackpad? And when I'm creating a new project, I get the service fabric category under the cloud category. And I can choose from, let me just see if I can enlarge this.
18:11
I'm sorry, I can't enlarge this. I don't have zoom in on here. But I can choose for an application with a stateless service and a stateful service.
18:21
And I can choose from an application with a stateless actor service and a stateful actor service. That's the choices I get. And if I choose the actor service, it will create a structure like this. It will create an application. It will create an interfaces project.
18:41
And it will create a service project. I'm not sure if the client project is in there as well. But anyway, I will go through all of them. So the application project is a special project. It has an application manifest and it has some extra tooling on it. So I can right click on it and I can say deploy.
19:04
And this will deploy my application to my cluster. So I have created a nine node cluster on my machine. This is a special cluster. Normally every machine has just one node which is configured. But for development purposes you can have a multi-node deployment or a multi-node cluster on your machine running.
19:26
So you can test your code. One of the benefits here is that it's not an emulator. It's the actual thing. So if your code works in here, it will work anywhere else where you want to deploy it.
19:44
Now the service fabric also comes with a little bit of tooling. As you can see, is this readable for everyone? I will read it up for you if you like.
20:01
You can see that my echo application has been deployed. It's a type and my type can have an application. It can have multiple versions of my application in fact. And my application consists of services. And in this case it's only one service. I can add as many services as I like. I can mix the reliable services API with the actor API.
20:28
No problem there. So I can make a stateless service that's calling somewhere an actor and does something on it. And as you can see, I have this stateless service.
20:43
And this stateless service consists of a number of partitions. Is it stateless? I'm not sure. So you start with the interface.
21:00
I will go through this later on in detail in slides. So I'm not going through the code entirely. The thing is, I can now run my client and it will get an actor.
21:25
And the actor will generate a random word. The first number you see in front is the actor ID. So zero through the number of partitions that I have. And that's basically it.
21:42
So really simple. Now I just want to show you that I can, with this tool, I can just kill a node if I like. So this one is located on node 2.
22:02
I can just kill node 2. I can stop it. And my service will run just as well. This is maybe not the best example because I have nine partitions so it's redundant all the way.
22:21
Okay, let me just start the node back up. Okay. So how does this work? I'll just take you through the slides. That's easier. So the service project is nothing more than a console application.
22:43
It's just a console application with a main method, which is your entry point. And in the main method you need to create a fabric runtime. And with that runtime you can register your actors. And the more actors you have, the more services it will create.
23:05
In this stateful demo I will show you the services that it creates. So a stateless actor always starts with an interface. And the interface needs to inherit from iActor. So if you're familiar with Project Orleans, this is basically the same as the grain marker interface.
23:23
The iGrainMarker interface. Also, as I said, it's all asynchronous. So the messages sent are all asynchronous. This needs to be asynchronous for it to work. The actual work is done in the actor. And this is just a class inheriting the actor class and implementing my interface.
23:52
Now I can reference actors. If I reference an actor from another service that's hosted in the same application, they will know about each other.
24:01
That's what I mean by name discovery. They will know about each other. I don't have to provide the application name because it just uses its own application name. In my sample I have a separate client. And I need to specify the application name and it will go out to the cluster locally.
24:22
And the way you create an actor is just by calling the actorProxy.create of type, the interface I specified. And we can provide it with a new ID. And an ID can be a long, a GUID, or a string. But it should always be wrapped inside an actor ID object.
24:45
So I mentioned that it was single-threaded. An actor is single-threaded. So how can it handle the large volumes? How does that work? Well, that works through a mechanism called turn-based concurrency. And it works something like this.
25:01
So the line is my actor and method A is called. Right after that, method B is called. But it needs to wait. It's been put on hold. And it will only return until my method A has returned. So all incoming requests are queued and stored until it's their turn.
25:26
Now stateful actors are really simple also. As I promised, it would be extremely simple. A stateful actor, we start out exactly the same by defining an interface that inherits from IActor.
25:40
The only difference is that the implementation of our actor implements from a generic class actor of type and then some object. That object represents our state. So if we look at that object, the only thing that needs to be done for that is it needs to be attributed with the data contract and data member attributes.
26:05
So it's serializable. Furthermore, we can just use this. There's just one thing. If you want to instantiate something like lists, which you normally would do in a constructor or something, just do this in the onActivateAsync method.
26:25
I'll talk about that later. And we can just store new players in the state. We can just call those properties and we can add values to them. We can get values out of them.
26:42
So as I said, the life cycle of an actor, what happens? So let's say we call some method that sets some value to 10. On the service fabric side, the actor is instantiated. So either it's still in memory somewhere and it's just fetched or it is instantiated.
27:07
It will load the state and the state will be stored on the actual node where the code is running. And at that point, it will call onActivateAsync. And we can override onActivateAsync to do some setup.
27:23
Think of this as your constructor. In onActivateAsync, we could potentially change the state. So to be absolutely certain, service fabric will replicate that state. So all replicas in the system will have your state.
27:45
Then the actual method is called. And when the actual method has changed the state, the state will be replicated again. And only then the response will be returned to the client.
28:02
When actors are idle for more than 60 seconds, I think, that's the default. You can change that. The actor will be deactivated so it won't take up your resources. And it will fire onDeactivateAsync. And you can override that as well. And you can implement some cleanup code in there.
28:25
Furthermore, if your actor is deactivated for more than, I believe it's an hour by default, it will be garbage collected.
28:40
Now you saw replicate state a number of times. We can speed things up by attributing certain methods with a read only attribute. If we are certain that the method call will not change the state, we can omit the state replication after the value is set.
29:03
And we do that by attributing the read only. So actors are like objects. You can store them in state, as I showed you in the state example, and you can pass them around. So an actor is a proxy. And whenever you call a method on an actor, it will, under the covers, it will find out where the other actor is and it will send messages.
29:33
But we don't have to worry about that. That's all abstracted for us. So what we're doing here is we're passing proxies and these proxies can be persisted in storage in state.
29:44
And they will be loaded next time the actor is activated again. That brings us to the potential reentrancy issue. So what if I have a chain of actor calls?
30:03
So actor A will call, a method will be called on actor A and it will call actor B and it will call actor C. And at the same time another call is being done on either actor A or maybe some other method A or maybe some other method.
30:26
We want to be able to call back to the originating actor as well. And we can. And we can do that because every method has its own unique context. So the system knows in what context you are and any other method call being done to that actor will have to wait until the rest is returned.
30:53
And it will return only if the first method is returned.
31:01
Now this is the default behavior. So we can do reentrancy by default. But you can imagine that the danger of circular dependency is there. So we can disable reentrancy. We can override the default behavior.
31:20
We can do that by attributing the actor class with the reentrant class and setting the reentrancy mode to disallowed. And that way we cannot, if the game actor calls a player actor, the player actor cannot call the game actor back.
31:44
So this is another neat thing. Timers and reminders. So timers you can compare with .net timers. You just start the timer and it will do some, it will process some logic in a periodic fashion.
32:03
But these timers do respect the turn-based concurrency. So they will not interfere with other calls. They will wait for it to finish and then it will execute. The thing about timers is they do not activate the actor.
32:21
So if the actor is deactivated, your timer is gone. You can explicitly unregister a timer. But they will disappear once your actor is deactivated. On the other hand, we have reminders. And reminders are like persistent timers. So we can register a reminder at any point.
32:45
And if my actor doesn't receive any calls and it will be deactivated, the reminder will reactivate it when it's time to do that. And it will execute its logic. So you specifically need to unregister reminders to stop them.
33:09
So if we look at the timer, it's really simple. We can say register timer and a good scenario for this is to just archive stale data. If you are collecting records or history in your actor, you just want a particular amount of records.
33:30
And everything that's older, you still want to keep that, but you want to move that to an external storage maybe for data analysis or something like that.
33:41
You can do that by using a timer. So as long as the object is active, it will periodically look at how many records there are or whatever logic you implement. And it will write it back. And if your actor is deactivated, the state doesn't change, so the timer doesn't need to run.
34:08
So reminders can be something that needs to be done periodically. Like in the IoT example, you could have specific devices that cannot push their telemetry or anything, but you need to talk to them periodically.
34:24
You need to poll them periodically. You can use like a reminder. So your actor is inactive, so it will be deactivated, but the reminder will activate it once it's time to poll the device in this scenario.
34:41
One special thing you need to do is that you need to implement the iRemindable interface on your actor. It requires you to implement receiveReminderAsync. And as you can see, we don't provide it with a delegate, but we provide it with a reminder name.
35:06
So we can register multiple reminders and just implement a switch statement like I've done here. And we can have a number of reminders and actions that need to be executed on that.
35:24
So your code gets very clean. Now in this example, and I'll show you in the demo later on, we can say start a game from a player. And it can say, well, register a reminder called top score and have it fire every three seconds.
35:47
And we do it like that. And as I said, the reminders, we need to unregister them when we want to stop. So if we started a game, we want to end the game. So in an end game method, we could get the reminder using getReminder with the name of the reminder and just unregister it if it's not null.
36:11
Another cool feature is events. So think of an actor having a reminder, doing some stuff on the background, but we want to know about certain events that happen.
36:22
So in my demo later on, I will have a player that will start a game. And once it's started a game, it will update its top score randomly. And every time it crosses some, it crosses the 50 boundary, it will raise an event.
36:43
We want to know about it. Events always start with an interface. Like everything in Service Fabric, it starts with an interface. And this interface needs to inherit the marker interface, iactor events. Now when I'm implementing my iPlayer actor interface, which inherits from iactor,
37:10
to make the eventing system possible, I need to inherit or implement the iactor event publisher interface as well. And this is also a marker interface.
37:22
It doesn't have any methods for us. It's just used to generate some code on the fly, so we get some extra methods when we're using the actor proxy. The iactor event publisher is a generic off-type, and we can provide it with our event interface.
37:48
So just to recap, in my example, I have the iPlayer events. And I want to report that another 50 points are added to my top score.
38:04
So when I want to fire an event, I can simply call getEvent off-type, and then my events interface. This method isn't there if your actor interface doesn't implement the iactor event publisher.
38:21
So this is one of the things that gets generated for us. And we can just call the method on that event. On the client side, we need to handle those events. So on the client side, we start by creating a class that implements our interface.
38:41
That's our contract. And in this case, I'm just doing a console.WriteLine. And like I said, when I get my reference to my player actor, I now have the subscribeAsync method to which I can subscribe my events. And the interface should match the class that I provide there.
39:07
So that's basically how you are doing events. Okay, let's just take a quick look at what it looks like.
39:22
Let me first remove the deployment. So I basically already showed you my code for the game scenario.
39:43
Just let me refresh this tool. And I already deployed the code because it's taking some time to get all the replicas replicated. As you can see, I have a game actor service and I have a player actor service.
40:03
And so for every type of actor I have, a new service is created. And each service has, I believe it's nine partitions. So where does this come from? I briefly talked about the application manifest and the configuration that's in there.
40:31
So here my services are defined in XML. And this is just generated stuff. So if I add a service or if I register a new actor, this will be generated for me.
40:45
So we don't have to dig into writing big XMLs or anything like that. We just need to understand them. So here's my service, my game actor service, and here's my other service, the player actor service. And you can see that it's of a certain type.
41:02
And we can specify the target replica set size. So we can say I want three replicas. So that means one primary and two secondaries. And I only want acknowledges to be sent back to the client until at least two replicas are completed.
41:25
And that will send an acknowledgement and asynchronously the third one will be completed as well. And you can see that I have a partitioning scheme where I say that I want nine partitions.
41:44
And that's what you're seeing here. So you're seeing the nine partitions and each partition has three nodes. So in this case it's node eight, node seven and node five. So a primary and two secondaries. And each one has that.
42:01
So the system will determine for any type of actor on what node it will be deployed. Now there's another way of looking at it. There's this nice little sample. Let me just, the other way around.
42:26
This is cluster monitor. And here you can see, if I refresh it, there it is. Here you can see, is this readable? Somewhat. If you can make out the colors then that's enough.
42:43
I will read the text. But you can see nine nodes over here. And they're all in different fold domains and upgrade domains. If you've worked with cloud services and web roles and work roles, you're familiar with that concept.
43:00
And you can see that there's two types of services deployed in each node. If I had more nodes, it wouldn't be in each node. But because I have the same amount of nodes as I have configured the amount of partitions, each node will have two. There's one node with the exception that's running this sample.
43:23
That's running the cluster monitor. So as you can see, the one I'm highlighting here, this is a primary on node eight. And as I hover over it, you can see two secondaries being highlighted on node five and node seven.
43:44
So they are dispersed over the cluster. They are never on the same machine. And that's what makes it redundant. Okay. So let's just go to the sample.
44:10
I'm getting notifications now because I tried this sample before and the application was still running. So my players have started games before. It's now starting nine new players or ten new players.
44:24
And they will start creating new games. And as you can see, some of the players will have a higher score because they have been running for about an hour. And there will be some players, the newly added players that will have a lower score.
44:42
But the ones with the notification, that's what happens with the event. Let me just... So I'm running this. I can just debug my application if...
45:03
Because that would be interesting, I think. Here's my player. So here's my reminder. And it calls update top score.
45:25
And a break point over here. Because that's another great thing. We can just debug this. I can just say... I can just say hit F5.
45:43
It will deploy the application. Now I'm not... I think it will first remove the application. Yes. So it will first remove my application. If I do it this way. I can use PowerShell to do rolling upgrades and that sort of thing.
46:01
And then it will deploy this version of the application which is exactly the same. And then it will start up. As you can see on build it added the application manifest so it needs to reload it.
46:22
I take it that my client will hang now. So it takes a little while for all the replicas to be replicated.
46:41
As you can see there are some yellow boxes here. So it will create the nine partitions all containing three replicas. And it will take some time for them to complete. But if I have one complete set I can start running. So I have a primary here but they are not complete yet.
47:14
This is why I deployed up front.
47:39
Okay well I'll switch back to the slides.
47:41
And when the slides are done I can show you the debugging because we're almost through. Okay so to recap. Reliable Actors API. That's what this talk was about. There was a little bit of introduction to the microservices stuff because this is all based on microservices.
48:04
So the specific service for a specific actor type is a microservice that handles the instantiation, the communication between actors, the placements and all that, the failover, the state management.
48:24
So the Actors API provides a distributed object model which is extremely suited for scalable scenarios.
48:40
There's automatic state management. We don't have to manage that. We don't have to create a dictionary or a queue or anything like that. State is managed for us. And it has some sophisticated features like the timers and reminders and events. I know that Project Orleans is a little bit further on.
49:00
But I'm sure that the more advanced features will flow into this as well. If we look at the Azure Service Fabric, the reliable platform on which this is all hosted. It provides the backbone of those reliable services. It does all the complicated stuff.
49:21
And it has done that for over five years now with services like Azure SQL Database, Service Bus. In fact, I think that the only reason that Service Bus was migrated to on-premises as quickly as it did was because it was hosted on this. And that's just my opinion. I'm not sure.
49:42
This is not an official statement, but I think that's it. Because this service was called Windows Fabric before. And that was one of the services that the Service Bus server version also deployed. It makes it very resilient to failure.
50:03
We can do rolling upgrades. We can even do a chaos monkey. We can invoke chaos on our cluster. Which will randomly do or simulate upgrades or replica replacements or failure or anything like that.
50:27
And we can just see if that impacts the performance and the availability of our services. Which is pretty neat. As you've seen, deploying an application is very fast. It's like seconds as opposed to the minutes of web and work rules.
50:47
And applications can consist of actor services and microservices or the reliable services together. So you can really create whatever you like. And you can make it as complex or as easy as you like.
51:04
With that, if there are any more questions? No questions? You are all basil, right? Okay, now I promised to show you the demo.
51:24
Because right now everything is blue. I did that through that. Let me quickly quit this.
51:40
So now it hits my breakpoint. And this is running the cloud. I can just step through this. Well, every three seconds this will be fired. Because it's the reminder and I've set it to fire at three seconds. So there it is again.
52:03
And if it reaches 50 somewhere. This will take some time.
52:24
If it reaches 50 it will fire my event. And my event will be handled in my client. So I can implement the event in different ways for different clients if I like. There we go.