Inlägg

Inlägg som CyberVillain har skrivit i forumet
Av CyberVillain

Nja, det ger lite extra klirr i kassan, men inget man kan leva på
Håller en del externa Seminarium via företag jag jobbar på. Knockout, SignalR och CQRS är det jag kör mest.

Detta ramverk som tråden handlar om är väl ett av det som folk visat mest intresse över, strax efter mitt SignalR ramverk som jag också skrivit om här.

Nackdelen med mina ramverk/seminarium är att de riktar sig till folk som har bra kunskap om tekniken de riktar sig mot. Ska man tjäna pengar kanske man borde rikta sig mer mot grundkurser. Men det är ju inte lika roligt

Av CyberVillain

Räcker att man kan visa att man jobbat i större projekt med SCRUM eller Kanban
Personligen när jag ansvarar för rekrytering, vilket händer ibland då jag är arkitekt, så ser jag nästan negativt på en person som har massor med cert. Jag ser myclet hellre att personen har egna projekt på fritiden tex på Github

Av CyberVillain

Därav ganska dumt att gå in så snävt, bättre utbilda sig / förkovra sig mer generellt så att man kan jobba över alla lager i ett system.
Själv jobbar jag med allt förutom integration och BI, mest för att det är mördande tråkigt.

Av CyberVillain

Ojdå, introducerade en liten bugg som kan visa sig om man rekursivt itererar över sin Vymodell (Subscriber).
Varje subscriber har en referens till en array som innehåller alla dess subscriptions, problemet är bara att varje subscription har en referens till sin subscriber. Så ramverk som förlitar sig på att rekursivt iterera över objekt utan att kolla om den redan besökt objektet (Lite naivt om du frågar mig) kommer att ge stack overflow.

Detta är åtgärdat i 1.0.57 av libbet

Av CyberVillain
Av CyberVillain

Ny version 1.0.51

  • Fixat trådsäkerhet, tack till de här på forumet som bollade idéer

  • Klienterna trottlar nu sina subscriptions så flera efterföljande subscriptions genererar bara ett anrop till servern

  • Man kan nu subscriba flera ggr till samma event men med olika constraint

Ny version av .NET klienten 1.0.53

  • Trottlar subscriptions så flera efterföljande subscriptions genererar bara ett anrop till servern

  • Man kan nu subscriba flera ggr till samma event men med olika constraint

Av CyberVillain

men alltså det där var ju bara för debug

edit: typ
http://jsfiddle.net/9SBMF/

Av CyberVillain

tom sweclockers har Adblocker detector så inga konstigheter.

Men om den är containern är tom så är det väll inte så svårt?

typ

setTimeout(function() { if($(".banners").html() === "") { console.log("Adblocker detected"); } }, 100);

Av CyberVillain

har du kollat med javascript hur din banner container ser ut efter att adblock gjort sin grej?

Av CyberVillain

Nope, open source. Fast Steve Sandersson grundaren av KO får rätt många tusen per kuvert när han håller ett seminarium så de tjänar pengar på andra sätt.

Håller själv mycket på med open source, skriver även bloggar och håller seminarium. hoppas köra seminarium på heltid en vacker dag

Av CyberVillain

Måste ge cred till KO teamet, mitt lib ovan slutade fungera med KO 3.0 då jag använde odokumenterade funktioner i KO. Då det ändå var publika delar av KO jag använde så lade jag upp en ticket på Github.

Nu när jag vaknade i morse så fick jag se denna pull request i inkorgen, snacka om service!
https://github.com/AndersMalmgren/Knockout.BindingConventions...

Av CyberVillain

Nej helt rätt SignalR och transport är ju den största boven i prestandan. Men, då det är en eventdriven design vill jag att den ska vara så snål det går på overhead, men jo det kan vara snudd på suboptimering detta.

Citat:

Att mäta hur många events du får på en viss tid mäter ju inte riktigt skalbarheten då du bara mäter den del där du inte har några lås medan de trådar som lägger till / tar bort prenumerationer inte alls tas i beaktande. Absolut bäst testresultat skulle du ju då få om enbart trådarna som kör () => handler(new MembersEvent()) får CPU-tid,

Helt sant, där av om du kollar den bortkommenterade koden

//for (var i = 0; i < 100; i++) //{ // eventProxy.Subscribe(CreateHubContext(), typeName, new string[0], null, null); //}

Där testade jag bara Handle på fyra trådar och lät subscribers vara statiskt till 100 (jag tog bort koden som trådade subscribe). Det testet som är commitat till git är mer för att försöka vara likt verkligheten vilket inte är lätt att simulera eller bencha. Saken är att den skalar inte så bra varken vid statiskt antal subscribe eller trådad subscribe

Helt sant att de borde vara volatile, men då de inte påverkar Benchmarket spelar den ingen större roll för mätvärdet.. men helt klart nått jag ska fixa.

Lol, code review at its best, hade helt missat att den var dubbeldeklarerad, kan förklara varför Resharper test runner gav helt andra tider än Console.Writlline som använder egen mätteknik. Good catch, will fix.

Jo, jag testade faktiskt även med explicita trådar men då det inte påverkade benchen så glömde jag att låta det vara kvar (Har ändrat testet så många ggr). Samt att den borde bara påverka om du har saker som tar lång tid, jag har ju helt stubbad bort SignalR så det enda jag testar är dataklassaserna och trådlogiken.

Benchmarken fungerar såhär

var timer = new System.Timers.Timer(benchmarkTime.TotalMilliseconds); timer.Elapsed += (s, e) => reset.Set(); var start = DateTime.Now; timer.Start(); reset.WaitOne(); running = false; Console.WriteLine("Catched events: {0} in {1}", events.Count, DateTime.Now - start);

Jag har en timer som flaggar för maintråden att avsluta testet, med den stora mätmängden (20 sekunder) borde det inte påverka mätresultatet.

Av CyberVillain

branch: Write lock + copy med IList

https://github.com/AndersMalmgren/SignalR.EventAggregatorProx...

branch: write lock + copy med fsharp
https://github.com/AndersMalmgren/SignalR.EventAggregatorProx...

FSharpListan är 4% snabbare men de skalar ju sklart lika då koden är identisk annars.

Jag vet inte om det är implementation eller mitt benchmarktest som är felet men de skalar nästan inte alls. typ 1.2 ggr snabbare med 4 trådar istället för 1

edit: Skrev om testet och lägger alla events i en ConcurenntBag och kör testet i 20 sekunder, sedan kollar jag hur många events som hamnade i bagen

Av CyberVillain

Jag har haft vattenkylning sedan mitten av 2000 talet och inte haft läckage en enda gång. Jag har dock aldrig haft kitsystem

Av CyberVillain

Jag har nu skrivit en implementation med F#'s FSharpList
Problemet är bara att det inte är helt lätt att bencha

https://github.com/AndersMalmgren/SignalR.EventAggregatorProx...
Som mitt enhetstest ser ut nu så för varje subscription som Handle metoden hanterar triggar denna kod i testet

count++; if (count == n) reset.Set();

När count nåt upp till n så avbryts testet. Problemet är bara att eftersom vi multitrådar betyder ju detta att det blir en race condition till count incrementen. Med andra ord om vi Triggar Handle metoden 1 miljon ggr kanske bara 600 000 eller färre faktiskt addas till counten. Vilket leder till att benchmarken blir helt fel. Om jag ändrar jag till

Interlocked.Increment(ref count); if (count == n) reset.Set();

Så tar interlocken så pass mycket att testet inte skalar med fler trådar. Mao i mitt nuvarande benchmark så vinner den vanliga implementaionen med lås över alla fyra metoder över write lås med immutble FSharpList och olåst read i Handle.

Dessutom vinner den med stor marginal, med lås över alla fyra metoder så tar det 10 sekunder att hantera 1 miljon events. Med Lås över bara write metoderna och FSharpList tar det 23 sekunder för en miljon events.

Testerna ovan gjordes med en tråd som pushar events, vilket inte är rättvist, så jag testade med fyra trådar som pushar events. Locklösningen skalar inte alls förståss, men det tråkiga är att write lock + Fsharplist skalar inte heller, det tar 20-24 sekunder (varier lite mellan varje körning).

Lite svårt att avgöra om det är kopiering av FSharpListan som tar resurser eller om det är Interlocked.Increment i benchmarken.

Av CyberVillain

Jag har hellre två skärmar med "mellanupplösning" än en med jättehög

Av CyberVillain

Bakfull som fan, man ska inte supa på vardagar.

För att svara på vilken implementation som är bäst måste man veta hur libbet kommer användas och det är ju upp till implementatören av libbet och beror mycket på hur det används i systemet och hur domänmodellen används. En av mina kollegor på inhouse använder tex libbet i ett domänmodell som är baserat på Eventsourcing, (Till skillnad från CRUD så spars alla state förändringar som events, man projicerar sedan dessa events på read modeller) i en sådan domänmodell där varje stateförändring är ett event kommer ju både sub / unsub och Handle trigga väldigt ofta.

Om vi tar mitt system på Banken där jag sitter som exempel, det var även detta system jag skapade libbet för. Det är en SPA (Single page application) och ungefär 70% av sidorna subbar och unsubbar när man lämnar dem. Detta betyder att det är enbart vid sidvisning som write metoderna används. Systemet är ett stödsystem för verksamhetsprocessen här på banken. Finns en batchmotor som när staten ändras på de jobben som körs så spottar den ut sig massor med events. Så i det systemet sker det väldigt sällan sub / sunsub men välldigt ofta Handle event. Jag tror ändå att det vanligaste kommer vara att man har mycket färre sub / unsubs än Handle, men säker kan man ju inte vara.

Hur som helst, jag tror fortfarande att en implementation av Write lock + copy och unlocked read är bäst mellanväg, sedadan är det bara att välja rätt implementation på listorna.

En sidenote, som klienten ser ut idag så throttlar den inte subscriptions, jag kan ta Demo siten i repository som exempel.

https://github.com/AndersMalmgren/SignalR.EventAggregatorProx...

subscribe: function () { signalR.eventAggregator.subscribe(SignalR.EventAggregatorProxy.Demo.MVC4.Events.StandardEvent, this.onEvent, this); signalR.eventAggregator.subscribe(SignalR.EventAggregatorProxy.Demo.MVC4.Events.GenericEvent.of("System.String"), this.onEvent, this); signalR.eventAggregator.subscribe(SignalR.EventAggregatorProxy.Demo.MVC4.Events.ConstrainedEvent, this.onEvent, this, { message: "HelloWorld" }); }

Varje anrop till signalR.eventAggregator.subscribe i javascriptet kommer resultera i en trigger av Subscribe metoden på servern, så enbart med en ansluten användare kommer vi få concurrent operations mot subscription listan. Min plan är att throttla signalR.eventAggregator.subscribe mao den väntar ett tick på systemtimern (ca 16ms) innan den faktiskt skickar sub'en. Då kommer de 3 subscriptions ovan skickas som tre i en lista istället.

Av CyberVillain

Grabbar jag är lite för full för att läsa era inlägg nu, burger night med grabbarna, lovar att läsa och återkomma imorn! Skitkul att ni har input!

Bonusbild

https://fbcdn-sphotos-g-a.akamaihd.net/hphotos-ak-prn2/1098132_1...

Av CyberVillain

Fast det är en copy av pekera den gör till en ny chunk av minne. aja, skit samma ska testa Immutable linked list iaf. Mest för att jag vill bencha den mot en List

Och då menar jag bencha den i mitt scenario

Av CyberVillain
Skrivet av Teknocide:

RemoveAll gör antagligen precis samma sak som koden jag skrev för den länkade listan, dvs skapar en ny lista och lägger i de objekt som inte matchar prediktatet. En naivare implementation som gjorde Remove() om och om igen skulle ge O(N^2). Även RemoveAt är O(N) på grund av minneskopieringen som görs (som är O(N))

Oj, blev galet där, fick för mig jag använde Remove, men det går ju inte
Memcopy shiftar bitarna så går inte att jämföra med O(N) i managed code. Men iaf, får testa lite och benchmarka.

edit: Däremot måste den ju göra Memcopy O(N2) där N = antalet borttagna element