18. Grains
• Fundamental building block
• Virtual Actor
• Effectively: Distributed Object
• Unit of computation + state
• Send/receive messages
• React to incoming messages
https://www.youtube.com/watch?time_continue=1426&v=Cj_jUHCXE3U
19. Grains
• Model objects in domain
• IoT device twins, user profiles, game sessions, auction items, blog posts, …
• Create graphs for computation/communication
• Fan-out, Fan-in & other processing patterns
• Concurrent workers, caches
• Distributed system realities
• Select an appropriate granularity
20. grain = identity + behavior [+ state]
User/fabio
in-memory,
persisted, or
stateless
class User : Grain, IUser
22. public class User : Grain, IUser
{
IGrainState<List<Message>> _messages;
public User([GrainState("messages")] IGrainState<List<Message>>
messageState)
=> _messages = messageState;
async Task SendMessage(IUser sender, string body)
{
_messages.Value.Add(new Message { Sender = sender, Body = body });
await _messages.WriteStateAsync();
}
Task<List<Message>> GetMessages() =>
Task.FromResult(_messages.Value);
}
23. // Get grain references. Synchronous & cheap
IUser me = client.GetGrain<IUser>("reuben");
IUser friend = client.GetGrain<IUser>("fabio");
// Call a grain
await friend.SendMessage(sender: me, body: "happy days :)");
// Check my mail for the 45th time today...
var messages = await me.GetMessages();
foreach (var msg in messages)
{
Console.WriteLine($"{msg.Sender.GetPrimaryKeyString()} says:
{msg.Body}");
}
35. type IdMapper () =
inherit Grain<IdMapperStateDto> ()
type IdMapperStateDto(state: IdMapperVersionedStateDto) =
member val State = state with get, set
new () =
IdMapperStateDto(IdMapperStateDtoV2.defaultState)
36. type IdMapperStateDtoV2 =
{ CatalogId: Guid; IsMapped: bool}
type IdMapperVersionedStateDto =
| V1 of Guid
| V2 of IdMapperStateDtoV2
module IdMapperStateDtoV2 =
let defaultState =
IdMapperVersionedStateDto.V2 {
CatalogId = Guid.Empty
IsMapped = false}
Just a short introduction of myself, my name is Harald Schult Ulriksen, I'm a software developer and I have been working with .net since beta 1. I'm employed by a small company called Aurum, currently working as a consultant for NRK, the Norwegian Broadcasting Corporation, the national broadcaster in norway, think BBC but smaller and in a strange language. At @NRK I'm on the API team in the "programspiller" / player project. The team is about 20 persons with a good split between designers, develoeprs, testers and project management. And it's a really great and competent team.
Brukerne finner ikke innholdet sitt og de blir forvirret av de to (tre) listene.
Modellen er veil, vi favorittmerket en episode og ikke serie. Når episoden vises kan den ha mistet rettigheter, man kan ha sett den ferdig og den er ikke lenger relevant.
Ting uten rettigheter
Riktig sted, serie typer
Her ligger problemet, reglene for hva som gjør at vi skal løfte opp innhold er kompliserte og vi ønsker å kunne endre dem uten at brukeren skal bli helt forvirret.
Velger man en serie skal man bli tatt til neste episode, men hva er neste episode? Hvis man ser på Heimebane er det ganske naturlig at det er den etter den man ser nå, ikke den som sist ble sluppet. Men nyhetene da? Du så dagsnytt sist torsdag, så da får du sist fredag som neste. Nei kanskje ikke.
Eller hva med nye episoder, du er på episode 3 i sesong 2, så kommer episode 4. Da ønsker vi nok å løfte frem at episode 4 har kommet, men hva hvis du er på episode 3 og det kommer episode 5? Nei, da har vi alt varslet om episode 4 så da trenger du ikke å få vite om at episode 5 er kommet. Men hva hvis du kom til episode 3 etter at episode 4 kom, slik at du ikke har fått med deg varsel om ny episode? Skal vi da varsle om episode 5? Og ja, hvis du er på episode 3 og den snart mister rettigheter, så er det vel passe kult om vi sier i fra 6 dager før eller noe slikt så du får sett den før vi mister rettigheter.
Store serier og sesonger, når vi treffer 4000 episoder i en serie som vi skal sjekke for brukerdata så kneler lua scriptet.
Vi holder ikke brukere lenge nok i Redis, de lastes for ofte opp fra databasen
Vi har ikke nok redis instanser, Hulu kjørte med 192 instanser som hver bestod av en master og 2 slaver.
Alle reglene vi ønsker oss
Serie er ikke bare serie.
Hvis vi drar en rask kobling til DDD land, og begynner å se på endringer som domenehendelser og hver enkelt favoritt som en egen instans, med ansvar for å kalkulere relevans basert på domenehendelsene, så begynner vi å se at det er ganske få domenehendelser, og hver enkelt kan ganske enkelt regne på om relevansen skal oppdateres.
Framework for distributed systems
Programming Model
Runtime
From Microsoft Research, Open Source under .NET Foundation
Built on .NET (Core), runs on:
Linux/Windows/macOS
Bare metal/Kubernetes/Service Fabric
Used by:
Microsoft (Azure, Xbox, Skype, others)
Halo, PlayFab, Gears of War, internal services
Honeywell, Gigya, Visa, NRK, TransUnion, Lebara, Drawboard, US NIST, others
Så hvorfor Orleans? Vel, vi ønsker ikke å mate systemet med lassevis av programmer og serier, men hvis vi antar at alt finnes i systemet så kan vi bare kalle på det når vi trenger det. Vi slipper å ha en programsManager som må sikre at det programmet vi skal ha tak i finnes som en actor, vi bare kaller på det og finnes det ikke så leser actoren selv inn program informasjonen ved oppstart.
Det samme gjelder streams, vi behøver ikke å vite om en stream finnes eller ikke, vi bare kaller på den. Skal vi sende data så bare gjør vi det, skal vi lese data så kan vi anta at det finnes noen som sender det også.
Vi er i Azure, og selv om vi hadde en anelse om at vi kom til å ende med k8s på Linux containere så var det greit å vite at løsningen kjørte godt i Azur
Men det viktigste var at vi visste det skalerte, det er lite til ingen plumbing kode å tenke på, Orleans rammeverket tar ansvar og vi sitter igjen med enkel kode.
Så, vi hadde bestemt oss for å teste Orleans, hva nå?
Man kan ikke si om en server er treg eller om den er død.
Hva er katalog – data on the inside / data on the outside – pat helland.
Innganger
Datamodell
Paging
Stateless
Prefer local
Hva er katalog – data on the inside / data on the outside – pat helland.
Innganger
Datamodell
Paging
Stateless
Prefer local
Hva er katalog – data on the inside / data on the outside – pat helland.
Innganger
Datamodell
Paging
Stateless
Prefer local
Hva er katalog – data on the inside / data on the outside – pat helland.
Innganger
Datamodell
Paging
Stateless
Prefer local
Flytt pil
Hva er katalog – data on the inside / data on the outside – pat helland.
Innganger
Datamodell
Paging
Stateless
Prefer local
Enrich other views where we does not have an index or set to work from.
Bloomfilter, https://en.wikipedia.org/wiki/Bloom_filter
Storage engines: Azure Table storage, Cosmos Db, Arango DB, Cassandra, Mongo Db, SQL Server, RavenDB, and I know someone had a BigQuery
If you’re not going to query the data outside of loading grain state
Versioning
Fortelle om Kubernetes. Namespace.
Deployments, replica sets, Membership provider.
Endre, service kaller pods. Det andre bare sier noe om pod’ene
Fortelle om deploymentløpet før man viser neste bilde
Kjøre tester i preprod, sammen også ta ned gammelt og nytt, skalere opp nytt og
Litt om deployment
Kjøre tester i preprod, sammen også ta ned gammelt og nytt, skalere opp nytt og
Feil med kø opprettelse som restartet. Utfordringer med å vite om ting er oppe. Mange i et cluster.
Grain Directory service is built on top of a Distributed Hash Table, which inherently is balanced. The directory service maps grains to activations, each silo owns part of the global mapping table, and this table is globally partitioned in a balanced way across all silos. We use consistent hashing with virtual buckets for that.