Jump to content

SUBIECTE NOI
« 1 / 5 »
RSS
Presbiopia - la 43 ani ?

Termen transcriere autovehicul

Cazare Timisoara pe 4-5 zile

Primele zile ale internetului per...
 Ditra 25

Casti USB-C ptr A-54

Aplicatie medicala / asistent med...

De ce vor atația politicieni...
 ERR_ADDRESS_UNREACHABLE

Legea 18/1968 Se mai aplica?

Digi conectare 2 routere prin fir

Succesiune notar versus instanta ...
 Montaj aer conditionat in balcon ...

Cont curent mulți valuta far...

Sugestii plan casa

Experiente cu firme care cumpara ...
 

Backend rapid pt forumuri – mii de cereri/secunda pe hardware modest

* * * * - 6 votes
  • Please log in to reply
80 replies to this topic

#19
edy_3dz

edy_3dz

    Rau sau bun

  • Grup: Senior Members
  • Posts: 3,241
  • Înscris: 30.08.2008

View Postdani.user, on 25 ianuarie 2017 - 22:28, said:

Cum numarul de linii de cod a depasit 10.000, imi permit sa ma cer parerea cu privire la cod.

Ar fi interesant cum il vad si cei ce scriu doar Java sau cei ce au/aveau multe prejudecati la adresa C++.

Salut, Dani! Ca si programator care scrie aproape exclusiv Java, imi permit sa las cateva comentarii:
  • Spatierea mi se pare un pic ciudata. De exemplu, COMMAND_HANDLER_METHOD( SHOW_VERSION ) l-as fi scris COMMAND_HANDLER_METHOD(SHOW_VERSION), sau if ( ! checkNumberOfParameters(parameters, output, 1)) return; ca si
    if (!checkNumberOfParameters(parameters, output, 1))
    {
    	return;
    }
    
    Imi place codul sa fie aerisit, doar ca pur si simplu sunt obisnuit sa nu pun spatiu intre parametri functiilor.
  • Faptul ca in constructorul clasei CommandHandler trebuie sa apelezi metoda setHandler() pentru fiecare comanda, mi se pare un pic error-prone. Eu as fi mers pe o structura prin care sa ajunga sa definesti o singura data comenzile, fara sa fie nevoie sa mai faci nimic altceva.
  • Codul e destul de self explanatory pe bucati, si exista si o minima documentatie pentru a build-ui proiectul, dar am dificultati in a gasi punctul de intrare in aplicatie, si sa vizualizez cum diferitele componente interactioneaza intre ele.
Ca si sugestie, cred ca ar fi fain daca ai deschide un pull request pentru fiecare feature implementat, chiar daca tot tu vei fi cel care ii va da merge. In primul rand pentru ca iti permite tot tie sa mai analizezi un pic codul, poate chiar dupa cateva zile, cand il vei privi cu alti ochi, si de asemenea ai putea integra niste unelte de analiza statica a codului care sa ruleze pe acele PR-uri. In al doilea rand, pentru ca ar permite unora sa lasa comentarii pe cod chiar dupa ce acele PR-uri au fost inchise.

Per total, pare un proiect fain, felicitari. Spor in continuare!

#20
dani.user

dani.user

    Guru Member

  • Grup: Senior Members
  • Posts: 30,233
  • Înscris: 24.02.2007
Mersi de feedback.

Imi place aerisirea, in cazul ! las mereu spatiu fiindca altfel sunt prea mari sansele sa citesc linia fara sa observ !

In java/c# as fi folosit adnotari pentru a declara comenzile. Aici n-am asa ceva la dispozitie asa ca trebuie sa mai scriu putin cod. Ar mai merge un source code parser care sa vada ce comenzi exista si sa insereze setHander inainte de compilare, dar parca nu-i chiar asa mult cod cat sa merite efortul. Lipsa unei comenzi arunca o exceptie, nu crapa aplicatia si e relativ usor de observat vreo scapare.

Punctul de intrare inca nu exista, doar main.cpp al testului. Va urma

Daca se va ajunge sa lucreze mai multi la proiect, pull request & friends vor fi calea de urmat. Cat timp exprim doar ideile mele, mi se pare putin prea multa birocratie. Am ideile notate in alta parte si prefer putin timp ce-l aloc sa-l petrec direct pentru treburi utile. Codul il refactorizez periodic pentru a-l curata.

Analiza statica am incercat odata dar s-a zapacit in codul inclus din boost. Analiza dinamica pentru leaks, cache si multithreading urmeaza dupa ce fac primul benchmark realist.

#21
dani.user

dani.user

    Guru Member

  • Grup: Senior Members
  • Posts: 30,233
  • Înscris: 24.02.2007
Odata implementata paginarea rezultatelor, am realizat primul test de performanta: https://github.com/d...k-Repository.md

Pe scurt: cu 500.000 de mesaje incarcate, avand in medie 1000 de bytes de text, aplicatia consuma ~ 1 GB RAM pe un Linux pe 64 biti si reuseste sa raspunda, cu un singur core, la mii de cereri/secunda.

Desigur, in varianta finala mai se adauga autorizarea si partea de HTTP, dar astea vor contribui cu un factor constant, independent de cantitatea de continut.

Eu sunt multumit de rezultate. Profilerul arata ca timpul majoritar petrecut e in cadrul ostream::operator<<

#22
dani.user

dani.user

    Guru Member

  • Grup: Senior Members
  • Posts: 30,233
  • Înscris: 24.02.2007
Pe moment suspend lucrul la proiect ca n-am timp de alocat UI-ului pentru a-l pune cu adevarat in valoare.

#23
dani.user

dani.user

    Guru Member

  • Grup: Senior Members
  • Posts: 30,233
  • Înscris: 24.02.2007
Daca e cineva curios de un raport de test code coverage:

Attached File  coverage.png   19.05K   122 downloads

#24
OriginalCopy

OriginalCopy

    I'm harmful, fear me please! :))

  • Grup: Senior Members
  • Posts: 27,268
  • Înscris: 10.08.2006
1. Nu vad de exemplu un serviciu care genereaza Uuid-uri, inclusiv un Uuid "zero". Mie personal asa imi place sa returnez "valori zero" cand nu exista value objects corecte, te scuteste de if-uri in apelant.
2. Si ca principiu, imi place sa am o clasa Application sau cum vrei s-o numesti, aici probabil Forum, care se ocupa cu dispatch de evenimente din viata aplicatiei (init, shutdown, handleCommand, etc) si cu managementul de plugins.
Pluginurile au dependinte intre ele, Application insasi e si ea un "plugin" - cel putin implementeaza o interfata comuna cu pluginurile adevarate gen Pluggable, deci initializarea lor trebuie sa se faca in ordinea sortarii topologice a grafului de dependinte.
Un astfel de plugin ar fi apoi tot balamucul cu HTTP & web.
3. CommandHandler mi se pare periculos, risca sa devina prea gras. Pentru inceput as separa comenzile de citire de comenzile care modifica state, si as numi "Command" doar ceea ce modifica state, restul e view.
4. Dupa 3, m-as gandi la aspectul accountability al securitatii, si as face asa incat anumite obiecte din domeniu executa anumite comenzi. Un GuestUser poate executa probabil doar comenzi gen ForgotPassword si Register, etc.
5. metodele skip din Context mi se par periculoase. Eu unul prefer sa am o interfata Environment care poate fi si Plugin (sau nu, e o chestiune de gust aici cred), vezi punctul 2, si implementari apoi gen BenchmarkingEnvironment.

Sunt biased de catre invataturile din jurul DDD si ale Unchiului Bob. Nu trebuie musai sa implementezi DDD ca sa iei cateva idei bune in general.

* Motivatia pentru 4 e sa "fortezi" securitatea din structura codului, din arhitectura. Din nou, te scapa de if-uri. If-urile sunt pacatoase pentru ca uiti ca ai nevoie de ele cand revii dupa mult timp asupra unui cod pe care nu l-ai mai vazut de ceva vreme
* Motivatia pentru 5 e analoga cu cea pentru 4, doar ca e vorba de mediul in care ruleaza aplicatia

** Pentru motivatiile anterioare, related talk: [ https://www.youtube-nocookie.com/embed/4F72VULWFvc?feature=oembed - Pentru incarcare in pagina (embed) Click aici ] de acelasi autor, probabil continutul e similar

#25
dani.user

dani.user

    Guru Member

  • Grup: Senior Members
  • Posts: 30,233
  • Înscris: 24.02.2007
Mersi mult pentru feedback. Cateva raspunsuri din partea mea:

1) UuidString la mine e un value-object, by default are valoarea 0. Random il generez cu o functie helper Forum::Entities::UuidString Forum::Repository::generateUUIDString(). Observ acum ca am uitat sa modific si namespace-ul cand am mutat functia dintr-o biblioteca in alta.

Mai am un caz special, const UserRef AnonymousUser; sa nu verific mereu pointerii.

2) Am in vedere o astfel de clasa pentru a lega componentele, dar dupa ce le termin de dezvoltat pe ele. Componentele actuale sunt gandite sa fie pluggable. De exemplu command handler primeste interfete in constructor pentru repositories.

3) Retinut, dar ma sperie usor ideea de a trebui sa ofer repositories ca dependinte catre mai multi command handlers.

4) Pentru securitate m-am gandit la interfete similare cu cele din repository care sa autorizeze sau nu o actiune. Ex. metoda care primeste un User& si un Thread& si verifica daca userul are voie sa scrie in acel thread. Ar fi apoi responsabilitatea repositoryului sa apeleze aceste metode si sa respinga mai sus actiunea daca implementarea concreta de autorizare zice ca nu-i voie. Ar prinde bine mai sus validarea, dar asa pot oferi direct referinte la business objects catre logica de autorizare decat sa transmit doar id'uri.

Userul nu va avea logica de autorizare, doar stocheaza informatii. Mi se pare mai usor de modificat daca am logica pentru diversele actiuni grupata in ceva gen LibForumAuthorization. Ma mai gandeam si la ceva scriptable in python pentru logica mai speciala de validare, dar cred ca-i prea mare bataie de cap.

5) Cred ca renunt la acele skip de tot. Complica treaba pentru beneficii minimale (popularea cu date random a benchmarkului nu-i chiar vitala sa dureze doar 1 min in loc de 1.5)

Imi plac si mie abordarile DDD, dar inca nu simt ca le am "in sange".

Edited by dani.user, 25 March 2017 - 22:51.


#26
OriginalCopy

OriginalCopy

    I'm harmful, fear me please! :))

  • Grup: Senior Members
  • Posts: 27,268
  • Înscris: 10.08.2006

View Postdani.user, on 25 martie 2017 - 22:40, said:

3) Retinut, dar ma sperie usor ideea de a trebui sa ofer repositories ca dependinte catre mai multi command handlers.
Nu iti inteleg nelinistea. Eu vad lucrurile asa:
1. "comenzile" "GET" sunt mutate intr-un nou plugin, "view",
2. pasul 1 "face loc" dpv. al efortului pentru adaugarea acestei noi dependinte (eu unul prefer in constructor, asa incat obiectele sa fie mereu valide) pentru command handlers ramasi
3. o HandlerFactory::getHandler<CommandHandler>() poate crea acesti handlers, injectand dependintele - te acopera in cazul in care se schimba constructorul handlerilor

Mie chiar imi place mai mult asa, datorita consistentei in crearea obiectelor, si a valorii de autodocumentare a claselor: se vede inca din constructor de ce ai nevoie. Adica nu ai sansa de a scrie new FooHandler(aberatie), arhitectura te forteaza sa ai fix ce ai nevoie, nu mai mult - fara inca un obiect intermediar care obstructioneaza adevaratele dependinte.

#27
dani.user

dani.user

    Guru Member

  • Grup: Senior Members
  • Posts: 30,233
  • Înscris: 24.02.2007
Am realizat o separare preliminara intre command si view. Am introdus si scheletul pentru viitorul sistem de autorizare.

#28
dani.user

dani.user

    Guru Member

  • Grup: Senior Members
  • Posts: 30,233
  • Înscris: 24.02.2007
Pana la urma am inceput sa reinventez roata pe partea de HTTP, for the fun of it. Au rezultat niste abordari interesante:
  • Model asincron
  • Procesare minimala nefiind o solutie generalista ci mulata strict pe nevoi
  • 0 alocare dinamica pe parcursul procesarii unei cereri (de cand s-a creat canalul TCP pana la controllerul ce va deservi cererea)
  • Procesari interesante ale sirurilor de caractere cand vine vorba de matching la headere.


#29
dani.user

dani.user

    Guru Member

  • Grup: Senior Members
  • Posts: 30,233
  • Înscris: 24.02.2007
Primele doua raspunsuri oferite via cereri HTTP

Attached File  s-1.png   7.28K   107 downloads

Attached File  s-2.png   46K   106 downloads

#30
dani.user

dani.user

    Guru Member

  • Grup: Senior Members
  • Posts: 30,233
  • Înscris: 24.02.2007
Vreo parere despre API-ul client prezentat (intr-o forma mai bruta) in https://github.com/d...Manager.cpp#L39 ?

Edited by dani.user, 18 April 2017 - 20:18.


#31
tatarduka

tatarduka

    Senior Member

  • Grup: Senior Members
  • Posts: 3,042
  • Înscris: 30.10.2006
Recunosc ca m-am uitat numai putin prin cod si cand am vazut ca EventObserver.cpp are aproape 1000 linii de cod m-am cam lasat.
ReadModel-urile le tii in memorie? Cand repornesti aplicatia, dai replay la toate evenimentele (sau si evenimentele sunt doar in memory momentan)?
Din ce vad, nu folosesti DDD. Cum asiguri integritatea datelor?

#32
dani.user

dani.user

    Guru Member

  • Grup: Senior Members
  • Posts: 30,233
  • Înscris: 24.02.2007

View Posttatarduka, on 27 iunie 2017 - 14:32, said:

ReadModel-urile le tii in memorie?

Si read si write stau in memorie. Scrii un mesaj nou si ceri apoi lista de topicuri, observi ca are totalul de mesaje actualizat.

View Posttatarduka, on 27 iunie 2017 - 14:32, said:

Cand repornesti aplicatia, dai replay la toate evenimentele (sau si evenimentele sunt doar in memory momentan)?

Da, la pornire are loc un replay al tuturor evenimentelor. E cel mai "lent" moment, dar benchmarkurile curente arata o ingestie a evenimentelor cu > 50 MB/s (excluzand viteza de citire de pe disc).

View Posttatarduka, on 27 iunie 2017 - 14:32, said:

Din ce vad, nu folosesti DDD.

Daca te referi la Domain Driven Design, eu zic ca-l folosesc. Intreg domeniul de business e modelat OOP, cu ceva cod functional pe ici pe colo.

View Posttatarduka, on 27 iunie 2017 - 14:32, said:

Cum asiguri integritatea datelor?

Fiecare actiune de write ajunge si pe filesystem. Exista o mica fereastra in care s-ar putea "lua curentul" inainte ca unele evenimente sa fie scrise, dar as zice ca e un risc minor. Evenimentele persistate au si un checksum ce ajuta la detectia vreunei potentiale coruperi.

Edited by dani.user, 09 August 2017 - 19:26.


#33
dani.user

dani.user

    Guru Member

  • Grup: Senior Members
  • Posts: 30,233
  • Înscris: 24.02.2007
Cineva curios depre cum arata primul prototip al interfetei grafice?


[ https://github.com/danij/Forum.WebClient/raw/master/screenshots/screenshot1.png - Pentru incarcare in pagina (embed) Click aici ]

Edited by dani.user, 11 August 2017 - 21:43.


#34
dolly_c

dolly_c

    Junior Member

  • Grup: Junior Members
  • Posts: 76
  • Înscris: 30.06.2017
Da. Am vrut sa vad mai clar de cand l-ati publicat, pe 11 august. Dar nu se poate vedea mai mare! Sunteti un programator bun, si cred ca sunteti pasionat de programare,

#35
dani.user

dani.user

    Guru Member

  • Grup: Senior Members
  • Posts: 30,233
  • Înscris: 24.02.2007
Drag de poza in alt tab sau click dreapta -> copy address -> deschidere in alt tab. Se va deschide la marimea obisnuita.

#36
dolly_c

dolly_c

    Junior Member

  • Grup: Junior Members
  • Posts: 76
  • Înscris: 30.06.2017

View Postdani.user, on 14 august 2017 - 16:30, said:

Drag de poza in alt tab sau click dreapta -> copy address -> deschidere in alt tab. Se va deschide la marimea obisnuita.
Va multumesc.

Anunturi

Second Opinion Second Opinion

Folosind serviciul second opinion ne puteți trimite RMN-uri, CT -uri, angiografii, fișiere .pdf, documente medicale.

Astfel vă vom putea da o opinie neurochirurgicală, fără ca aceasta să poată înlocui un consult de specialitate. Răspunsurile vor fi date prin e-mail în cel mai scurt timp posibil (de obicei în mai putin de 24 de ore, dar nu mai mult de 48 de ore). Second opinion – Neurohope este un serviciu gratuit.

www.neurohope.ro

0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users

Forumul Softpedia foloseste "cookies" pentru a imbunatati experienta utilizatorilor Accept
Pentru detalii si optiuni legate de cookies si datele personale, consultati Politica de utilizare cookies si Politica de confidentialitate