@startuml Vue de contexte
[client ...3000] as c
[Service] as s
[Base de donnée] as BD
title Diagramme de contexte
c "1..3000"->"1" s
s "1"->"1" BD

@enduml

@startuml Vue composant et connecteur
title Vue composant et connecteur
[client 1] as c1
[client 2] as c2
[client ...3000] as c3
[loadBalancer] as LB
[Service 1] as s1
[Service 2] as s2
[Service 3] as s3
[Base de donnée] as BD

c1 --> LB
c2 --> LB
c3 --> LB
LB --> s1
LB --> s2
LB --> s3
s1 --> BD
s2 --> BD 
s3 --> BD

@enduml

@startuml C&C with interface
title Vue composants et connecteurs avec interfaces explicites
[client 1] as c1
[client 2] as c2
[client ...3000] as c3
[loadBalancer] as LB
[Service 1] as s1
[Service 2] as s2
[Service 3] as s3
[Base de donnée] as BD
interface IService as islb
interface IService as is1
interface IService as is2
interface IService as is3
interface Ibd as ibd

c1 --> islb
c2 --> islb
c3 --> islb
islb <|.. LB
LB --> is1
LB --> is2
LB --> is3
is1 <|..s1
is2 <|..s2
is3 <|..s3

s1 --> ibd
s2 --> ibd
s3 --> ibd
ibd <|.. BD
@enduml



@startuml solution-Vue composant et connecteur
title Vue composant et connecteur
[client 1] as c1
[client 2] as c2
[client ...3000] as c3
[loadBalancer] as LB
[Service 1] as s1
[Service 2] as s2
[Service 3] as s3
[Base de donnée] as BD
[Orchestrateur] as O
O ..|> IOrchestrateur

LB ..|> ILoadBalancerCtrl
O ..> ILoadBalancerCtrl
LB ..> IOrchestrateur

c1 --> LB
c2 --> LB
c3 --> LB
LB --> s1
LB --> s2
LB --> s3
s1 --> BD
s2 --> BD 
s3 --> BD

@enduml

@startuml  solution-ping 
skinparam style strictuml 
Participant "main:App" as App
Participant ":Client" as C
participant "orchestrateur:IOrchestrateur" as O << (I,#ADD1B2) >>
participant "orchestrateurServices:List<IService>" as OLS
participant "loadBalancer:ILoadBalancerCtrl" as LBC << (I,#ADD1B2) >>
' participant "loadbalancer2:LoadBalancer" as LB2 << (C,#ADD1B2) >>
participant "<<loadBalancer2:ILoadBalancerCtrl" as ILB2C << (I,#ADD1B2) >>
participant "<<loadBalancer2:IService" as IS << (I,#ADD1B2) >>
participant "<<loadBalancer2Services>>\n:List<Service>" as LS
participant "nextService:IService" as NS
participant "nextServiceRequests:List<RequesInfot>" as NSR
note right of App: bd = new BD()\nservice1 = new Service(bd:Ibd)\nservcice2=new Service(bd:Ibd)\nservice3 = new Service(bd:Ibd)\nloadBalancer = new LoadBalancer([service1,service2,service3])
App -> O**: create(loadBalancer:ILoadBalancer,services:List<IService>,bd:Ibd)
O -> OLS**: create()
note right of App: loadBalancer.setOrchestrator(orchestrator)
loop  i < services.length
   O -> OLS:  add(services[i])
end
note right of O: each secondes\nTactique ping/echo 
O  ->  LBC: echo = ping()
opt echo  == null
O -> LBC: kill()
destroy LBC
note right of O: tactique de spare et reconfiguration
O -> ILB2C**: create(adresseIp:string, \nport:integer,\norchestrateur:IOrchestrateur)
activate ILB2C
ILB2C -> O: services:List<IService> = getServices()
ILB2C -> ILB2C: setServices(services:List<IService>)
ILB2C -> ILB2C: setOrchestrateur(orchestrateur4:IOrchestrateur)
deactivate ILB2C

O -> ILB2C: echo = ping()
note right of O: Client utilise une tactique de retry \navec un délai d'au moins un seconde et 3 tentatives
C -> IS: info = request(.....)
IS -> IS: nbSevice = getNbServices()
IS -> IS: nbRequest = getNbRequest()

note left of IS: Il manque de service
alt  nbservice  <  nbRequest / 10
    IS -> O: bd:Ibd = getBd()
    IS -> IS: addNewService(bd:IBD)
    activate IS
        IS -> NS**: nextService = create(ibd:IBD)
        NS -> NSR**: create()
        loop true
            NS -> NSR: requestInfo = pop()
            NS -> NS: execute(requestInfo)
            opt stopIfNoMoreRequest
            opt nextServiceRequest.length == 0
            NS -> NS: exit()
            end
            end
        end
        IS -> LS:add(nextService:IService)
        IS -> O: addService(nextService:IService)
        O -> OLS: add(nextService:Iservice)
        IS -> NS: info = request(requestInfo:RequestInfo)
        NS -> NSR: add(requestInfo:RequestInfo)
    deactivate IS
else
    note right of IS: round robin ou spécifier comment vous choisissez\nle prochain service à utiliser
    IS -> IS: nextService=getNextAvailableService()
    IS -> NS: info = request(requestInfo:RequestInfo)
    NS -> NSR: add(requestInfo:RequestInfo)

   
end
note left of IS: il y a trop de service
opt  nbservice  >  nbRequest / 10
    IS -> NS: stopWhenNoMoreRequest()
    NS -> NS: stopWhenNoMoreRequest()
    IS->LS:remove(nextService)
    IS->O:removeService(nextService)
    O -> OLS: remove(nextService:Iservice)
    ' IS->NS: kill()
end
note right of O: Il faudrait étudier comment fonctionne le reply pour permettre au service de répondre directement au client sans passer par le loadBalancer pour minimiser la charge de celui-ci
@enduml