рдЕрдиреБрд░реЛрдзреЛрдВ рдФрд░ рдЙрдирдХреЗ рд╕рдорд╛рдзрд╛рдиреЛрдВ рдХреЗ рдмреИрдЪ рдкреНрд░рд╕рдВрд╕реНрдХрд░рдг рдХреА рд╕рдорд╕реНрдпрд╛рдПрдВ (рднрд╛рдЧ 1)

рд▓рдЧрднрдЧ рд╕рднреА рдЖрдзреБрдирд┐рдХ рд╕реЙрдлреНрдЯрд╡реЗрдпрд░ рдЙрддреНрдкрд╛рджреЛрдВ рдореЗрдВ рдХрдИ рд╕реЗрд╡рд╛рдПрдВ рд╢рд╛рдорд┐рд▓ рд╣реИрдВред рдЕрдХреНрд╕рд░, рд▓рдВрдмреЗ рд╕рдордп рддрдХ рдЗрдВрдЯрд░-рд╕рд░реНрд╡рд┐рд╕ рдЪреИрдирд▓ рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рд╕рдордп рдкреНрд░рджрд░реНрд╢рди рд╕рдорд╕реНрдпрд╛рдУрдВ рдХрд╛ рд╕реНрд░реЛрдд рдмрди рдЬрд╛рддрд╛ рд╣реИред рдЗрд╕ рддрд░рд╣ рдХреА рд╕рдорд╕реНрдпрд╛ рдХрд╛ рдорд╛рдирдХ рд╕рдорд╛рдзрд╛рди рдХрдИ рдЪреМрд░рд╛рд╣реЛрдВ рдХреЗ рдЕрдиреБрд░реЛрдзреЛрдВ рдХреЛ рдПрдХ рдкреИрдХреЗрдЬ рдореЗрдВ рдкреИрдХ рдХрд░рдирд╛ рд╣реИ, рдЬрд┐рд╕реЗ рдмреИрдЪрд┐рдВрдЧ рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИред

рдпрджрд┐ рдЖрдк рдмреИрдЪ рдкреНрд░реЛрд╕реЗрд╕рд┐рдВрдЧ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рдЖрдк рдкреНрд░рджрд░реНрд╢рди рдпрд╛ рдХреЛрдб рдХреА рд╕рдордЭ рдХреЗ рдорд╛рдорд▓реЗ рдореЗрдВ рдЗрд╕рдХреЗ рдкрд░рд┐рдгрд╛рдо рд╕реЗ рдЦреБрд╢ рдирд╣реАрдВ рд╣реЛ рд╕рдХрддреЗред рдпрд╣ рддрд░реАрдХрд╛ рдХреЙрд▓рд░ рдХреЗ рд▓рд┐рдП рдЙрддрдирд╛ рдЖрд╕рд╛рди рдирд╣реАрдВ рд╣реИ рдЬрд┐рддрдирд╛ рдЖрдк рд╕реЛрдЪ рд╕рдХрддреЗ рд╣реИрдВред рд╡рд┐рднрд┐рдиреНрди рдЙрджреНрджреЗрд╢реНрдпреЛрдВ рдФрд░ рд╡рд┐рднрд┐рдиреНрди рд╕реНрдерд┐рддрд┐рдпреЛрдВ рдХреЗ рд▓рд┐рдП, рдирд┐рд░реНрдгрдп рдмрд╣реБрдд рднрд┐рдиреНрди рд╣реЛ рд╕рдХрддреЗ рд╣реИрдВред рд╡рд┐рд╢рд┐рд╖реНрдЯ рдЙрджрд╛рд╣рд░рдгреЛрдВ рдкрд░, рдореИрдВ рдХрдИ рджреГрд╖реНрдЯрд┐рдХреЛрдгреЛрдВ рдХреЗ рдкреЗрд╢реЗрд╡рд░реЛрдВ рдФрд░ рд╡рд┐рдкрдХреНрд╖реЛрдВ рдХреЛ рджрд┐рдЦрд╛рдКрдВрдЧрд╛ред

рдбреЗрдореЛ рдкреНрд░реЛрдЬреЗрдХреНрдЯ


рд╕реНрдкрд╖реНрдЯрддрд╛ рдХреЗ рд▓рд┐рдП, рдЙрд╕ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдХреЗ рдХрд┐рд╕реА рдПрдХ рд╕реЗрд╡рд╛ рдХреЗ рдЙрджрд╛рд╣рд░рдг рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд░реЗрдВ рдЬрд┐рд╕ рдкрд░ рдореИрдВ рд╡рд░реНрддрдорд╛рди рдореЗрдВ рдХрд╛рдо рдХрд░ рд░рд╣рд╛ рд╣реВрдВред

рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП рдордВрдЪ рдХреА рдкрд╕рдВрдж рдХрд╛ рд╕реНрдкрд╖реНрдЯреАрдХрд░рдг
рдЦрд░рд╛рдм рдкреНрд░рджрд░реНрд╢рди рдХреА рд╕рдорд╕реНрдпрд╛ рдХрд╛рдлреА рд╕рд╛рдорд╛рдиреНрдп рд╣реИ рдФрд░ рдХрд┐рд╕реА рднреА рд╡рд┐рд╢рд┐рд╖реНрдЯ рднрд╛рд╖рд╛рдУрдВ рдФрд░ рдкреНрд▓реЗрдЯрдлрд╛рд░реНрдореЛрдВ рдкрд░ рд▓рд╛рдЧреВ рдирд╣реАрдВ рд╣реЛрддреА рд╣реИред рдпрд╣ рд▓реЗрдЦ рдХрд╛рд░реНрдпреЛрдВ рдФрд░ рд╕рдорд╛рдзрд╛рдиреЛрдВ рдХреЛ рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╕реНрдкреНрд░рд┐рдВрдЧ + рдХреЛрдЯрд▓рд┐рди рдХреЛрдб рдЙрджрд╛рд╣рд░рдгреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдЧрд╛ред рдХреЛрдЯрд▓рд┐рди рдЬрд╛рд╡рд╛ рдФрд░ рд╕реА # рдбреЗрд╡рд▓рдкрд░реНрд╕ рдХреЗ рд▓рд┐рдП рд╕рдорд╛рди рд░реВрдк рд╕реЗ рд╕рдордЭрдиреЗ рдпреЛрдЧреНрдп (рдпрд╛ рд╕рдордЭ рд╕реЗ рдмрд╛рд╣рд░) рд╣реИ, рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдХреЛрдб рдЬрд╛рд╡рд╛ рдХреА рддреБрд▓рдирд╛ рдореЗрдВ рдЕрдзрд┐рдХ рдХреЙрдореНрдкреИрдХреНрдЯ рдФрд░ рд╕рдордЭрдиреЗ рдпреЛрдЧреНрдп рд╣реИред рд╢реБрджреНрдз рдЬрд╛рд╡рд╛ рдбреЗрд╡рд▓рдкрд░реНрд╕ рдХреЗ рд▓рд┐рдП рд╕рдордЭ рдХреА рд╕реБрд╡рд┐рдзрд╛ рдХреЗ рд▓рд┐рдП, рдореИрдВ рдХреЛрдЯрд▓рд┐рди рдХрд╛рд▓реЗ рдЬрд╛рджреВ рд╕реЗ рдмрдЪреВрдВрдЧрд╛ рдФрд░ рдХреЗрд╡рд▓ рд╕рдлреЗрдж (рд▓реЛрдореНрдмреЛрдХ рдХреА рднрд╛рд╡рдирд╛ рдореЗрдВ) рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реВрдВрдЧрд╛ред рдХреБрдЫ рд╡рд┐рд╕реНрддрд╛рд░ рд╡рд┐рдзрд┐рдпрд╛рдВ рд╣реЛрдВрдЧреА, рд▓реЗрдХрд┐рди рд╡реЗ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рд╕рднреА рдЬрд╛рд╡рд╛ рдкреНрд░реЛрдЧреНрд░рд╛рдорд░ рдХреЗ рд▓рд┐рдП рд╕реНрдерд┐рд░ рд╡рд┐рдзрд┐рдпреЛрдВ рдХреЗ рд░реВрдк рдореЗрдВ рдкрд░рд┐рдЪрд┐рдд рд╣реИрдВ, рдЗрд╕рд▓рд┐рдП рдпрд╣ рдереЛрдбрд╝реА рдЪреАрдиреА рд╣реЛрдЧреА рдЬреЛ рдбрд┐рд╢ рдХреЗ рд╕реНрд╡рд╛рдж рдХреЛ рдЦрд░рд╛рдм рдирд╣реАрдВ рдХрд░реЗрдЧреАред

рджрд╕реНрддрд╛рд╡реЗрдЬрд╝ рдЕрдиреБрдореЛрджрди рд╕реЗрд╡рд╛ рд╣реИред рдХреЛрдИ рд╡реНрдпрдХреНрддрд┐ рдПрдХ рджрд╕реНрддрд╛рд╡реЗрдЬрд╝ рдмрдирд╛рддрд╛ рд╣реИ рдФрд░ рдЙрд╕реЗ рдЪрд░реНрдЪрд╛ рдХреЗ рд▓рд┐рдП рдкреНрд░рд╕реНрддреБрдд рдХрд░рддрд╛ рд╣реИ, рдЬрд┐рд╕рдХреЗ рджреМрд░рд╛рди рд╕рдВрдкрд╛рджрди рдХрд┐рдП рдЬрд╛рддреЗ рд╣реИрдВ, рдФрд░ рдЕрдВрддрддрдГ рджрд╕реНрддрд╛рд╡реЗрдЬрд╝ рд╕реБрд╕рдВрдЧрдд рд╣реЛрддрд╛ рд╣реИред рд╕реБрд▓рд╣ рд╕реЗрд╡рд╛ рд╕реНрд╡рдпрдВ рджрд╕реНрддрд╛рд╡реЗрдЬреЛрдВ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдХреБрдЫ рднреА рдирд╣реАрдВ рдЬрд╛рдирддреА рд╣реИ: рдпрд╣ рдХреЗрд╡рд▓ рдЫреЛрдЯреЗ рдЕрддрд┐рд░рд┐рдХреНрдд рдХрд╛рд░реНрдпреЛрдВ рдХреЗ рд╕рд╛рде рд╕рдордиреНрд╡рдпрдХреЛрдВ рдХреА рдПрдХ рдЪреИрдЯ рд╣реИ, рдЬрд┐рд╕реЗ рд╣рдо рдпрд╣рд╛рдВ рдкрд░ рд╡рд┐рдЪрд╛рд░ рдирд╣реАрдВ рдХрд░реЗрдВрдЧреЗред

рдЗрд╕рд▓рд┐рдП, рдЙрдирдореЗрдВ рд╕реЗ рдкреНрд░рддреНрдпреЗрдХ рдореЗрдВ рдкреНрд░рддрд┐рднрд╛рдЧрд┐рдпреЛрдВ рдХреЗ рдкреВрд░реНрд╡рдирд┐рд░реНрдзрд╛рд░рд┐рдд рд╕реЗрдЯ рдХреЗ рд╕рд╛рде рдЪреИрдЯ рд░реВрдо (рджрд╕реНрддрд╛рд╡реЗрдЬреЛрдВ рдХреЗ рдЕрдиреБрд░реВрдк) рд╣реИрдВред рдирд┐рдпрдорд┐рдд рдЪреИрдЯ рдХреЗ рд░реВрдк рдореЗрдВ, рд╕рдВрджреЗрд╢реЛрдВ рдореЗрдВ рдкрд╛рда рдФрд░ рдлрд╝рд╛рдЗрд▓реЗрдВ рд╣реЛрддреА рд╣реИрдВ рдФрд░ рдЙрддреНрддрд░ рдФрд░ рдЖрдЧреЗ рд╣реЛ рд╕рдХрддреЗ рд╣реИрдВ:

data class ChatMessage (
   // nullable persist
   val id : Long ? = null ,
   /** */
   val author : UserReference ,
   /** */
   val message : String ,
   /** */
   // - JPA+ null,
   val files : List < FileReference > ? = null ,
   /** , */
   val replyTo : ChatMessage ? = null ,
   /** , */
   val forwardFrom : ChatMessage ? = null
)


рдлрд╝рд╛рдЗрд▓ рдФрд░ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХреЗ рд▓рд┐рдВрдХ рдЕрдиреНрдп рдбреЛрдореЗрди рдХреЗ рд▓рд┐рдВрдХ рд╣реИрдВред рдпрд╣ рд╣рдорд╛рд░реЗ рд╕рд╛рде рдЗрд╕ рддрд░рд╣ рд░рд╣рддрд╛ рд╣реИ:

typealias FileReference = Long
typealias UserReference = Long

рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдбреЗрдЯрд╛ Keycloak рдореЗрдВ рд╕рдВрдЧреНрд░рд╣реАрдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ рдФрд░ REST рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдкреБрдирд░реНрдкреНрд░рд╛рдкреНрдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдПрдХ рд╣реА рдлрд╛рдЗрд▓ рдХреЗ рд▓рд┐рдП рдЬрд╛рддрд╛ рд╣реИ: рдлрд╛рдЗрд▓реЗрдВ рдФрд░ рдореЗрдЯрд╛-рдЬрд╛рдирдХрд╛рд░реА рдЙрдирдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдПрдХ рдЕрд▓рдЧ рдлрд╝рд╛рдЗрд▓ рднрдВрдбрд╛рд░рдг рд╕реЗрд╡рд╛ рдореЗрдВ рд░рд╣рддреА рд╣реИред

рдЗрди рд╕реЗрд╡рд╛рдУрдВ рдХреЗ рд▓рд┐рдП рд╕рднреА рдХреЙрд▓ рднрд╛рд░реА рдЕрдиреБрд░реЛрдз рд╣реИрдВ ред рдЗрд╕рдХрд╛ рдорддрд▓рдм рдпрд╣ рд╣реИ рдХрд┐ рдЗрди рдЕрдиреБрд░реЛрдзреЛрдВ рдХреЗ рдкрд░рд┐рд╡рд╣рди рдХреЗ рд▓рд┐рдП рдУрд╡рд░рд╣реЗрдб рдЙрд╕ рд╕рдордп рдХреА рддреБрд▓рдирд╛ рдореЗрдВ рдмрд╣реБрдд рдЕрдзрд┐рдХ рд╣реИ рдЬреЛ рдЙрдиреНрд╣реЗрдВ рддреГрддреАрдп-рдкрдХреНрд╖ рд╕реЗрд╡рд╛ рджреНрд╡рд╛рд░рд╛ рд╕рдВрд╕рд╛рдзрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд▓реЗрддрд╛ рд╣реИред рд╣рдорд╛рд░реЗ рдкрд░реАрдХреНрд╖рдг рд╕реНрдЯреИрдВрдб рдкрд░, рдРрд╕реА рд╕реЗрд╡рд╛рдУрдВ рдХреЗ рд▓рд┐рдП рд╡рд┐рд╢рд┐рд╖реНрдЯ рдХреЙрд▓ рд╕рдордп 100 рдПрдордПрд╕ рд╣реИ, рдЗрд╕рд▓рд┐рдП рднрд╡рд┐рд╖реНрдп рдореЗрдВ рд╣рдо рдЗрди рдирдВрдмрд░реЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВрдЧреЗред

рд╣рдореЗрдВ рд╕рднреА рдЖрд╡рд╢реНрдпрдХ рдЬрд╛рдирдХрд╛рд░реА рдХреЗ рд╕рд╛рде рдЕрдВрддрд┐рдо рдПрди рд╕рдВрджреЗрд╢реЛрдВ рдХреЛ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рд╕рд░рд▓ REST рдирд┐рдпрдВрддреНрд░рдХ рдмрдирд╛рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред рдпрд╣реА рд╣реИ, рд╣рдо рдорд╛рдирддреЗ рд╣реИрдВ рдХрд┐ рджреГрд╢реНрдпрдкрдЯрд▓ рдореЗрдВ, рд╕рдВрджреЗрд╢ рдореЙрдбрд▓ рд▓рдЧрднрдЧ рд╕рдорд╛рди рд╣реИ рдФрд░ рд╣рдореЗрдВ рд╕рднреА рдбреЗрдЯрд╛ рднреЗрдЬрдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред рджреГрд╢реНрдпрдкрдЯрд▓ рдореЙрдбрд▓ рдХреЗ рдмреАрдЪ рдЕрдВрддрд░ рдпрд╣ рд╣реИ рдХрд┐ рдлрд╝рд╛рдЗрд▓ рдФрд░ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХреЛ рд▓рд┐рдВрдХ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЙрдиреНрд╣реЗрдВ рдереЛрдбрд╝рд╛ рдбрд┐рдХреНрд░рд┐рдкреНрдЯреЗрдб рд░реВрдк рдореЗрдВ рдкреНрд░рд╕реНрддреБрдд рдХрд░рдирд╛ рд╣реЛрдЧрд╛:

/** */
data class ReferenceUI (
   /** url */
   val ref : String ,
   /** */
   val name : String
)
data class ChatMessageUI (
   val id : Long ,
   /** */
   val author : ReferenceUI ,
   /** */
   val message : String ,
   /** */
   val files : List < ReferenceUI >,
   /** , */
   val replyTo : ChatMessageUI ? = null ,
   /** , */
   val forwardFrom : ChatMessageUI ? = null
)


рд╣рдореЗрдВ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ:

interface ChatRestApi {
   fun getLast ( n : Int ) : List < ChatMessageUI >
}


рдкреЛрд╕реНрдЯрдлрд┐рдХреНрд╕ рдпреВрдЖрдИ рдХрд╛ рдорддрд▓рдм рд╣реИ, рдлреНрд░рдВрдЯрдПрдВрдб рдХреЗ рд▓рд┐рдП рдбреАрдЯреАрдУ рдореЙрдбрд▓, рдЬреЛ рдХрд┐ рд╣рдореЗрдВ REST рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рджреЗрдирд╛ рдЪрд╛рд╣рд┐рдПред

рдпрд╣рд╛рдБ рдпрд╣ рдЖрд╢реНрдЪрд░реНрдпрдЬрдирдХ рд▓рдЧ рд╕рдХрддрд╛ рд╣реИ рдХрд┐ рд╣рдо рдХрд┐рд╕реА рднреА рдЪреИрдЯ рдЖрдЗрдбреЗрдВрдЯрд┐рдлрд╝рд╛рдпрд░ рдХреЛ рдкрд╛рд╕ рдирд╣реАрдВ рдХрд░рддреЗ рд╣реИрдВ рдФрд░ рдпрд╣рд╛рдБ рддрдХ рдХрд┐ рдЪреИрдЯрдореИрд╕реЗрдЬ / рдЪреИрдЯрдореЗрд╕реЗрдЬрдпреВрдЖрдИ рдореЙрдбрд▓ рдореЗрдВ рднреА рдпрд╣ рдирд╣реАрдВ рд╣реИред рдореИрдВрдиреЗ рдРрд╕рд╛ рдЙрджреНрджреЗрд╢реНрдп рд╕реЗ рдХрд┐рдпрд╛, рддрд╛рдХрд┐ рдЙрджрд╛рд╣рд░рдгреЛрдВ рдХреЗ рд▓рд┐рдП рдХреЛрдб рдХреЛ рдЕрд╡реНрдпрд╡рд╕реНрдерд┐рдд рди рдХрд┐рдпрд╛ рдЬрд╛рдП (рдЪреИрдЯ рдЕрд▓рдЧ-рдерд▓рдЧ рд╣реИрдВ, рдЗрд╕рд▓рд┐рдП рд╣рдо рдорд╛рди рд╕рдХрддреЗ рд╣реИрдВ рдХрд┐ рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдПрдХ рд╣реИ)ред

рджрд╛рд░реНрд╢рдирд┐рдХ рд░рд┐рдЯреНрд░реАрдЯ
ChatMessageUI рд╡рд░реНрдЧ рдФрд░ ChatRestApi.getLast рд╡рд┐рдзрд┐ рджреЛрдиреЛрдВ рд╣реА рд╕реВрдЪреА рдбреЗрдЯрд╛ рдкреНрд░рдХрд╛рд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВ, рдЬрдмрдХрд┐ рдпрд╣ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдПрдХ рдЖрджреЗрд╢рд┐рдд рд╕реЗрдЯ рд╣реИред JDK рдореЗрдВ, рдпрд╣ рд╕рднреА рдЦрд░рд╛рдм рд╣реИ, рдЗрд╕рд▓рд┐рдП рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рд╕реНрддрд░ рдкрд░ рддрддреНрд╡реЛрдВ рдХреЗ рдХреНрд░рдо рдХреА рдШреЛрд╖рдгрд╛ рдХрд░рдирд╛ (рдЬреЛрдбрд╝рдиреЗ рдФрд░ рдирд┐рдХрд╛рд▓рдиреЗ рдкрд░ рдЖрджреЗрд╢ рдмрдирд╛рдП рд░рдЦрдирд╛) рд╡рд┐рдлрд▓ рд╣реЛ рдЬрд╛рдПрдЧрд╛ред рдЗрд╕рд▓рд┐рдП рдЙрди рдорд╛рдорд▓реЛрдВ рдореЗрдВ рд╕реВрдЪреА рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рдЖрдо рдмрд╛рдд рд╣реИ, рдЬрд╣рд╛рдВ рдЖрдкрдХреЛ рдСрд░реНрдбрд░ рд╕реЗрдЯ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ (рдЕрднреА рднреА рдПрдХ рд▓рд┐рдВрдХреНрдбрд╢реИрд╕реЗрдЯ рд╣реИ, рд▓реЗрдХрд┐рди рдпрд╣ рдПрдХ рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдирд╣реАрдВ рд╣реИ)ред

рдПрдХ рдорд╣рддреНрд╡рдкреВрд░реНрдг рд╕реАрдорд╛: рд╣рдо рдорд╛рдирддреЗ рд╣реИрдВ рдХрд┐ рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛рдУрдВ рдХреА рдХреЛрдИ рд▓рдВрдмреА рд╢реНрд░реГрдВрдЦрд▓рд╛ рдпрд╛ рдЖрдЧреЗ рдирд╣реАрдВ рд╣реИред рдпрд╣реА рд╣реИ, рд╡реЗ рд╣реИрдВ, рд▓реЗрдХрд┐рди рдЙрдирдХреА рд▓рдВрдмрд╛рдИ рддреАрди рд╕рдВрджреЗрд╢реЛрдВ рд╕реЗ рдЕрдзрд┐рдХ рдирд╣реАрдВ рд╣реИред рдлреНрд░рдВрдЯ-рдПрдВрдб рд╕рдВрджреЗрд╢ рд╢реНрд░реГрдВрдЦрд▓рд╛ рдХреЛ рд╕рдВрдкреВрд░реНрдгрддрд╛ рдореЗрдВ рдкреНрд░реЗрд╖рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдПред

рдмрд╛рд╣рд░реА рд╕реЗрд╡рд╛рдУрдВ рд╕реЗ рдбреЗрдЯрд╛ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдРрд╕реЗ рдПрдкреАрдЖрдИ рд╣реИрдВ:

interface ChatMessageRepository {
   fun findLast ( n : Int ) : List < ChatMessage >
}
data class FileHeadRemote (
   val id : FileReference ,
   val name : String
)
interface FileRemoteApi {
   fun getHeadById ( id : FileReference ) : FileHeadRemote
   fun getHeadsByIds ( id : Set < FileReference > ) : Set < FileHeadRemote >
   fun getHeadsByIds ( id : List < FileReference > ) : List < FileHeadRemote >
   fun getHeadsByChat () : List < FileHeadRemote >
}
data class UserRemote (
   val id : UserReference ,
   val name : String
)
interface UserRemoteApi {
   fun getUserById ( id : UserReference ) : UserRemote
   fun getUsersByIds ( id : Set < UserReference > ) : Set < UserRemote >
   fun getUsersByIds ( id : List < UserReference > ) : List < UserRemote >
}


рдпрд╣ рджреЗрдЦрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ рдХрд┐ рдмреИрдЪ рдкреНрд░рд╕рдВрд╕реНрдХрд░рдг рд╢реБрд░реВ рдореЗрдВ рдмрд╛рд╣рд░реА рд╕реЗрд╡рд╛рдУрдВ рдХреЗ рд▓рд┐рдП рдкреНрд░рджрд╛рди рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛, рдФрд░ рджреЛрдиреЛрдВ рдорд╛рдорд▓реЛрдВ рдореЗрдВ: рд╕реЗрдЯ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ (рддрддреНрд╡реЛрдВ рдХреЗ рдЖрджреЗрд╢ рдХреЛ рд╕рдВрд░рдХреНрд╖рд┐рдд рдХрд┐рдП рдмрд┐рдирд╛, рдЕрджреНрд╡рд┐рддреАрдп рдХреБрдВрдЬреА рдХреЗ рд╕рд╛рде) рдФрд░ рд╕реВрдЪреА рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ (рдбреБрдкреНрд▓рд┐рдХреЗрдЯ рд╣реЛ рд╕рдХрддреЗ рд╣реИрдВ - рдСрд░реНрдбрд░ рд╕рдВрд░рдХреНрд╖рд┐рдд рд╣реИ)ред

рд╕рд░рд▓ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди


Naive рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди


рд╣рдорд╛рд░реЗ REST рдХрдВрдЯреНрд░реЛрд▓рд░ рдХрд╛ рдкрд╣рд▓рд╛ рдЕрдиреБрднрд╡рд╣реАрди рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреБрдЫ рдЗрд╕ рддрд░рд╣ рд╕реЗ рджрд┐рдЦрд╛рдИ рджреЗрдЧрд╛:

class ChatRestController (
   private val messageRepository : ChatMessageRepository ,
   private val userRepository : UserRemoteApi ,
   private val fileRepository : FileRemoteApi
) : ChatRestApi {
   override fun getLast ( n : Int ) =
     messageRepository . findLast ( n )
       . map { it . toFrontModel () }

   private fun ChatMessage . toFrontModel () : ChatMessageUI =
     ChatMessageUI (
       id = id ?: throw IllegalStateException ( " $ this must be persisted" ) ,
       author = userRepository . getUserById ( author ) . toFrontReference () ,
       message = message ,
       files = files ?. let { files ->
         fileRepository . getHeadsByIds ( files )
           . map { it . toFrontReference () }
} ?: listOf () ,
       forwardFrom = forwardFrom ?. toFrontModel () ,
       replyTo = replyTo ?. toFrontModel ()
)
}

рд╕рдм рдХреБрдЫ рдмрд╣реБрдд рд╕реНрдкрд╖реНрдЯ рд╣реИ, рдФрд░ рдпрд╣ рдПрдХ рдмрдбрд╝рд╛ рдкреНрд▓рд╕ рд╣реИред

рд╣рдо рдмреИрдЪ рдкреНрд░реЛрд╕реЗрд╕рд┐рдВрдЧ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВ рдФрд░ рдмреИрдЪреЛрдВ рдореЗрдВ рдмрд╛рд╣рд░реА рд╕реЗрд╡рд╛ рд╕реЗ рдбреЗрдЯрд╛ рдкреНрд░рд╛рдкреНрдд рдХрд░рддреЗ рд╣реИрдВред рд▓реЗрдХрд┐рди рдкреНрд░рджрд░реНрд╢рди рдХреЗ рд╕рд╛рде рдХреНрдпрд╛ рд╣реЛ рд░рд╣рд╛ рд╣реИ?

рдкреНрд░рддреНрдпреЗрдХ рд╕рдВрджреЗрд╢ рдХреЗ рд▓рд┐рдП, UserRemoteApi рдХреЗ рд▓рд┐рдП рдПрдХ рдХреЙрд▓ рд▓реЗрдЦрдХ рдлрд╝реАрд▓реНрдб рдкрд░ рдбреЗрдЯрд╛ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдФрд░ рд╕рднреА рд╕рдВрд▓рдЧреНрди рдлрд╝рд╛рдЗрд▓реЛрдВ рдХреЛ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП FileRemoteApi рдкрд░ рдПрдХ рдХреЙрд▓ рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ред рд▓рдЧрддрд╛ рддреЛ рд╕рдм рд╣реИред рдорд╛рди рд▓реЗрдВ рдХрд┐ ChatMessage рдХреЗ рд▓рд┐рдП рдлрд╝реЙрд░рдлрд╝реЙрд░реНрдо рдФрд░ рд░рд┐рдкреНрд▓рд╛рдИ рдлрд╝реАрд▓реНрдб рдкреНрд░рд╛рдкреНрдд рдХрд┐рдП рдЧрдП рд╣реИрдВ рддрд╛рдХрд┐ рдЗрд╕рдХреЗ рд▓рд┐рдП рдЕрддрд┐рд░рд┐рдХреНрдд рдХреЙрд▓ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рди рд╣реЛред рд▓реЗрдХрд┐рди рдЙрдиреНрд╣реЗрдВ ChatMessageUI рдореЗрдВ рдмрджрд▓рдиреЗ рд╕реЗ рдкреБрдирд░рд╛рд╡реГрддреНрддрд┐ рд╣реЛ рдЬрд╛рдПрдЧреА, рдпрд╛рдиреА рдХреЙрд▓ рдХрд╛рдЙрдВрдЯ рдХрд╛ рдкреНрд░рджрд░реНрд╢рди рдмрд╣реБрдд рдмрдврд╝ рд╕рдХрддрд╛ рд╣реИред рдЬреИрд╕рд╛ рдХрд┐ рд╣рдордиреЗ рдкрд╣рд▓реЗ рдЙрд▓реНрд▓реЗрдЦ рдХрд┐рдпрд╛ рд╣реИ, рдорд╛рди рд▓реЗрдВ рдХрд┐ рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдмрд╣реБрдд рдЕрдзрд┐рдХ рдиреЗрд╕реНрдЯрд┐рдВрдЧ рдирд╣реАрдВ рд╣реИ рдФрд░ рд╢реНрд░реГрдВрдЦрд▓рд╛ рддреАрди рд╕рдВрджреЗрд╢реЛрдВ рддрдХ рд╕реАрдорд┐рдд рд╣реИред

рдкрд░рд┐рдгрд╛рдорд╕реНрд╡рд░реВрдк, рд╣рдореЗрдВ рдкреНрд░рддрд┐ рд╕рдВрджреЗрд╢ рдмрд╛рд╣рд░реА рд╕реЗрд╡рд╛рдУрдВ рд╕реЗ рджреЛ рд╕реЗ рдЫрд╣ рдХреЙрд▓ рдФрд░ рдкреВрд░реЗ рд╕рдВрджреЗрд╢ рдкреИрдХреЗрдЯ рдореЗрдВ рдПрдХ рдЬреЗрдкреАрдП рдХреЙрд▓ рдорд┐рд▓рддрд╛ рд╣реИред рдХреЙрд▓ рдХреА рдХреБрд▓ рд╕рдВрдЦреНрдпрд╛ 2 * рдПрди + 1 рд╕реЗ 6 * рдПрди + 1 рддрдХ рднрд┐рдиреНрди рд╣реЛрдЧреАред рд╡рд╛рд╕реНрддрд╡рд┐рдХ рдЗрдХрд╛рдЗрдпреЛрдВ рдореЗрдВ рдпрд╣ рдХрд┐рддрдирд╛ рд╣реИ? рдорд╛рди рд▓реЗрдВ рдХрд┐ рдХрд┐рд╕реА рдкреЗрдЬ рдХреЛ рд░реЗрдВрдбрд░ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЖрдкрдХреЛ 20 рдкреЛрд╕реНрдЯ рдХреА рдЬрд░реВрд░рдд рд╣реИред рдЙрдиреНрд╣реЗрдВ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдЖрдкрдХреЛ 4 рдПрд╕ рд╕реЗ 10 рдПрд╕ рддрдХ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИред рдмреЗрдХрд╛рд░! рдореИрдВ 500 рдПрдордПрд╕ рд╕реЗ рдорд┐рд▓рдирд╛ рдЪрд╛рд╣реВрдВрдЧрд╛ред рдФрд░ рдЪреВрдВрдХрд┐ рдлреНрд░рдВрдЯ-рдПрдВрдб рдПрдХ рд╕рд╣рдЬ рд╕реНрдХреНрд░реЙрд▓ рдмрдирд╛рдиреЗ рдХрд╛ рд╕рдкрдирд╛ рджреЗрдЦ рд░рд╣рд╛ рдерд╛, рдЗрд╕рд▓рд┐рдП рдЗрд╕ рдПрдВрдбрдкреЙрдЗрдВрдЯ рдХреА рдкреНрд░рджрд░реНрд╢рди рдЖрд╡рд╢реНрдпрдХрддрд╛рдУрдВ рдХреЛ рджреЛрдЧреБрдирд╛ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред

рдкреЗрд╢реЗрд╡рд░реЛрдВ:

  1. рдХреЛрдб рд╕рдВрдХреНрд╖рд┐рдкреНрдд рдФрд░ рд╕реНрд╡-рджрд╕реНрддрд╛рд╡реЗрдЬреАрдХрд░рдг (рд╕рдорд░реНрдерди рдХрд╛ рд╕рдкрдирд╛) рд╣реИред
  2. рдХреЛрдб рд╕рд░рд▓ рд╣реИ, рдЗрд╕рд▓рд┐рдП рдкреИрд░ рдореЗрдВ рдЧреЛрд▓реА рдорд╛рд░рдиреЗ рдХреЗ рд▓рдЧрднрдЧ рдХреЛрдИ рдЕрд╡рд╕рд░ рдирд╣реАрдВ рд╣реИрдВред
  3. рдмреИрдЪ рдкреНрд░рд╕рдВрд╕реНрдХрд░рдг рд╡рд┐рджреЗрд╢реА рдирд╣реАрдВ рджрд┐рдЦрддрд╛ рд╣реИ рдФрд░ рд╡реНрдпрд╡рд╕реНрдерд┐рдд рд░реВрдк рд╕реЗ рддрд░реНрдХ рдореЗрдВ рдлрд┐рдЯ рд╣реЛрддрд╛ рд╣реИред
  4. рддрд░реНрдХ рдкрд░рд┐рд╡рд░реНрддрди рдЖрд╕рд╛рдиреА рд╕реЗ рдХрд┐рдП рдЬрд╛рдПрдВрдЧреЗ рдФрд░ рд╕реНрдерд╛рдиреАрдп рд╣реЛрдВрдЧреЗред

рдХрдо:

рдЗрд╕ рддрдереНрдп рдХреЗ рдХрд╛рд░рдг рднрдпрд╛рдирдХ рдкреНрд░рджрд░реНрд╢рди рдХрд┐ рдкреИрдХреЗрдЬ рдмрд╣реБрдд рдЫреЛрдЯреЗ рд╣реИрдВред

рдпрд╣ рджреГрд╖реНрдЯрд┐рдХреЛрдг рдЕрдХреНрд╕рд░ рд╕рд╛рдзрд╛рд░рдг рд╕реЗрд╡рд╛рдУрдВ рдпрд╛ рдкреНрд░реЛрдЯреЛрдЯрд╛рдЗрдк рдореЗрдВ рджреЗрдЦрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред рдпрджрд┐ рдкрд░рд┐рд╡рд░реНрддрди рдХреА рдЧрддрд┐ рдорд╣рддреНрд╡рдкреВрд░реНрдг рд╣реИ, рддреЛ рдпрд╣ рдкреНрд░рдгрд╛рд▓реА рдХреЛ рдЬрдЯрд┐рд▓ рдмрдирд╛рдиреЗ рдХреЗ рд▓рд╛рдпрдХ рд╣реИред рдЙрд╕реА рд╕рдордп, рд╣рдорд╛рд░реА рдмрд╣реБрдд рд╣реА рд╕рд░рд▓ рд╕реЗрд╡рд╛ рдХреЗ рд▓рд┐рдП, рдкреНрд░рджрд░реНрд╢рди рднрдпрд╛рдирдХ рд╣реИ, рдЗрд╕рд▓рд┐рдП рдЗрд╕ рджреГрд╖реНрдЯрд┐рдХреЛрдг рдХреА рдкреНрд░рдпреЛрдЬреНрдпрддрд╛ рдХрд╛ рджрд╛рдпрд░рд╛ рдмрд╣реБрдд рд╕рдВрдХреАрд░реНрдг рд╣реИред

Naive рд╕рдорд╛рдирд╛рдВрддрд░ рдкреНрд░рд╕рдВрд╕реНрдХрд░рдг


рдЖрдк рд╕рднреА рд╕рдВрджреЗрд╢реЛрдВ рдХреЛ рд╕рдорд╛рдирд╛рдВрддрд░ рдореЗрдВ рд╕рдВрд╕рд╛рдзрд┐рдд рдХрд░рдирд╛ рд╢реБрд░реВ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ - рдЗрд╕рд╕реЗ рд╕рдВрджреЗрд╢реЛрдВ рдХреА рд╕рдВрдЦреНрдпрд╛ рдХреЗ рдЖрдзрд╛рд░ рдкрд░ рд╕рдордп рдореЗрдВ рд░реИрдЦрд┐рдХ рд╡реГрджреНрдзрд┐ рд╕реЗ рдЫреБрдЯрдХрд╛рд░рд╛ рдорд┐рд▓реЗрдЧрд╛ред рдпрд╣ рд╡рд┐рд╢реЗрд╖ рд░реВрдк рд╕реЗ рдЕрдЪреНрдЫрд╛ рддрд░реАрдХрд╛ рдирд╣реАрдВ рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рдпрд╣ рдмрд╛рд╣рд░реА рд╕реЗрд╡рд╛ рдкрд░ рдПрдХ рдмрдбрд╝реЗ рд╢рд┐рдЦрд░ рд▓реЛрдб рдХреЛ рдмрдврд╝рд╛рд╡рд╛ рджреЗрдЧрд╛ред

рд╕рдорд╛рдирд╛рдВрддрд░ рдкреНрд░рд╕рдВрд╕реНрдХрд░рдг рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдирд╛ рдмрд╣реБрдд рд╕рд░рд▓ рд╣реИ:

override fun getLast ( n : Int ) =
   messageRepository . findLast ( n ) . parallelStream ()
     . map { it . toFrontModel () }
     . collect ( toList ())


рд╕рдорд╛рдирд╛рдВрддрд░ рд╕рдВрджреЗрд╢ рдкреНрд░рд╕рдВрд╕реНрдХрд░рдг рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реБрдП, рд╣рдо 300-700 рдПрдордПрд╕ рдЖрджрд░реНрд╢ рд░реВрдк рд╕реЗ рдкреНрд░рд╛рдкреНрдд рдХрд░рддреЗ рд╣реИрдВ, рдЬреЛ рдПрдХ рднреЛрд▓реЗ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреЗ рд╕рд╛рде рдмрд╣реБрдд рдмреЗрд╣рддрд░ рд╣реИ, рд▓реЗрдХрд┐рди рдлрд┐рд░ рднреА рдкрд░реНрдпрд╛рдкреНрдд рддреЗрдЬреА рд╕реЗ рдирд╣реАрдВред

рдЗрд╕ рджреГрд╖реНрдЯрд┐рдХреЛрдг рдХреЗ рд╕рд╛рде, userRepository рдФрд░ fileRepository рдХреЗ рдЕрдиреБрд░реЛрдзреЛрдВ рдХреЛ рд╕рдорд╛рди рд░реВрдк рд╕реЗ рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛, рдЬреЛ рдмрд╣реБрдд рдХреБрд╢рд▓ рдирд╣реАрдВ рд╣реИред рдЗрд╕реЗ рдареАрдХ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдЖрдкрдХреЛ рдХреЙрд▓ рдХреЗ рддрд░реНрдХ рдХреЛ рдХрд╛рдлреА рдмрджрд▓рдирд╛ рд╣реЛрдЧрд╛ред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдХрдореНрдкреЗрдХреНрд╢рдирд╕реНрдЯреЗрдЬ (рдЙрд░реНрдл рдХрдВрдкреНрд▓реАрдЯреЗрдмрд▓ рдлрд╝реЙрдЗрд▓) рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ:

private fun ChatMessage . toFrontModel () : ChatMessageUI =
   CompletableFuture . supplyAsync {
     userRepository . getUserById ( author ) . toFrontReference ()
   } . thenCombine (
     files ?. let {
       CompletableFuture . supplyAsync {
         fileRepository . getHeadsByIds ( files ) . map { it . toFrontReference () }
}
} ?: CompletableFuture . completedFuture ( listOf ())
) { author , files ->
     ChatMessageUI (
       id = id ?: throw IllegalStateException ( " $ this must be persisted" ) ,
       author = author ,
       message = message ,
       files = files ,
       forwardFrom = forwardFrom ?. toFrontModel () ,
       replyTo = replyTo ?. toFrontModel ()
)
   } . get () !!


рдпрд╣ рджреЗрдЦрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ рдХрд┐ рд╢реБрд░реВ рдореЗрдВ рд╕рд░рд▓ рдореИрдкрд┐рдВрдЧ рдХреЛрдб рдХрдо рд╕реНрдкрд╖реНрдЯ рд╣реЛ рдЧрдпрд╛ рд╣реИред рдРрд╕рд╛ рдЗрд╕рд▓рд┐рдП рд╣реИ рдХреНрдпреЛрдВрдХрд┐ рд╣рдореЗрдВ рдмрд╛рд╣рд░реА рд╕реЗрд╡рд╛ рдХреЙрд▓ рдХреЛ рдЕрд▓рдЧ рдХрд░рдирд╛ рдерд╛ рдЬрд╣рд╛рдВ рд╕реЗ рдкрд░рд┐рдгрд╛рдо рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛ред рдпрд╣ рдЕрдкрдиреЗ рдЖрдк рдореЗрдВ рдмреБрд░рд╛ рдирд╣реАрдВ рд╣реИред рд▓реЗрдХрд┐рди рдХреЙрд▓ рдХрд╛ рд╕рдВрдпреЛрдЬрди рдмрд╣реБрдд рд╕реБрдВрджрд░ рдирд╣реАрдВ рджрд┐рдЦрддрд╛ рд╣реИ рдФрд░ рдПрдХ рд╡рд┐рд╢рд┐рд╖реНрдЯ рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛рд╢реАрд▓ "рдиреВрдбрд▓" рдЬреИрд╕рд╛ рджрд┐рдЦрддрд╛ рд╣реИред

рдпрджрд┐ рдЖрдк рдХреЛрд░рдЖрдЙрдЯ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рд╕рдм рдХреБрдЫ рдЕрдзрд┐рдХ рд╕рднреНрдп рджрд┐рдЦрд╛рдИ рджреЗрдЧрд╛:

private fun ChatMessage . toFrontModel () : ChatMessageUI =
   join (
     { userRepository . getUserById ( author ) . toFrontReference () } ,
     { files ?. let { fileRepository . getHeadsByIds ( files )
       . map { it . toFrontReference () } } ?: listOf () }
   ) . let { ( author , files ) ->
     ChatMessageUI (
       id = id ?: throw IllegalStateException ( " $ this must be persisted" ) ,
       author = author ,
       message = message ,
       files = files ,
       forwardFrom = forwardFrom ?. toFrontModel () ,
       replyTo = replyTo ?. toFrontModel ()
)
   }


рдЬрд╣рд╛рдВ:

fun < A , B > join ( a : () -> A , b : () -> B ) =
   runBlocking ( IO ) {
     awaitAll ( async { a () } , async { b () } )
   } . let {
     it [ 0 ] as A to it [ 1 ] as B
   }


рд╕реИрджреНрдзрд╛рдВрддрд┐рдХ рд░реВрдк рд╕реЗ, рдЗрд╕ рддрд░рд╣ рдХреЗ рд╕рдорд╛рдирд╛рдВрддрд░ рдкреНрд░рд╕рдВрд╕реНрдХрд░рдг рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ, рд╣рдореЗрдВ 200-400 рдПрдордПрд╕ рдорд┐рд▓рддреЗ рд╣реИрдВ, рдЬреЛ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рд╣рдорд╛рд░реА рдЙрдореНрдореАрджреЛрдВ рдХреЗ рдХрд░реАрдм рд╣реИред

рджреБрд░реНрднрд╛рдЧреНрдп рд╕реЗ, рдРрд╕рд╛ рдЕрдЪреНрдЫрд╛ рд╕рдорд╛рдирд╛рдВрддрд░ рдирд╣реАрдВ рд╣реЛрддрд╛ рд╣реИ, рдФрд░ рдЕрджрд╛рдпрдЧреА рдмрд╣реБрдд рдХреНрд░реВрд░ рд╣реИ: рдПрдХ рд╣реА рд╕рдордп рдореЗрдВ рдХрд╛рдо рдХрд░рдиреЗ рд╡рд╛рд▓реЗ рдХреБрдЫ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛рдУрдВ рдХреЗ рд╕рд╛рде, рдЕрдиреБрд░реЛрдзреЛрдВ рдХреА рдПрдХ рдЧрдбрд╝рдЧрдбрд╝рд╛рд╣рдЯ рд╕реЗрд╡рд╛рдУрдВ рдкрд░ рдЧрд┐рд░ рдЬрд╛рдПрдЧреА, рдЬреЛ рдЕрднреА рднреА рд╕рдорд╛рдирд╛рдВрддрд░ рдореЗрдВ рд╕рдВрд╕рд╛рдзрд┐рдд рдирд╣реАрдВ рд╣реЛрдЧреА, рдЗрд╕рд▓рд┐рдП рд╣рдо рдЕрдкрдиреЗ рдЙрджрд╛рд╕ 4 рдПрд╕ рдкрд░ рд▓реМрдЯ рдЖрдПрдВрдЧреЗред

20 рд╕рдВрджреЗрд╢реЛрдВ рдХреЛ рд╕рдВрд╕рд╛рдзрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдРрд╕реА рд╕реЗрд╡рд╛ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдкрд░ рдореЗрд░рд╛ рдкрд░рд┐рдгрд╛рдо 1300-1700 рдПрдордПрд╕ рд╣реИред рдпрд╣ рдкрд╣рд▓реЗ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреА рддреБрд▓рдирд╛ рдореЗрдВ рддреЗрдЬрд╝ рд╣реИ, рд▓реЗрдХрд┐рди рдлрд┐рд░ рднреА рд╕рдорд╕реНрдпрд╛ рдХрд╛ рд╕рдорд╛рдзрд╛рди рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИред

рд╕рдорд╛рдирд╛рдВрддрд░ рдкреНрд░рд╢реНрдиреЛрдВ рдХрд╛ рд╡реИрдХрд▓реНрдкрд┐рдХ рдЙрдкрдпреЛрдЧ
рдпрджрд┐ рддреГрддреАрдп-рдкрдХреНрд╖ рд╕реЗрд╡рд╛рдУрдВ рдореЗрдВ рдмреИрдЪ рдкреНрд░рд╕рдВрд╕реНрдХрд░рдг рдкреНрд░рджрд╛рди рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ рддреЛ рдХреНрдпрд╛ рд╣реЛрдЧрд╛? рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдЖрдк рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рд╡рд┐рдзрд┐рдпреЛрдВ рдХреЗ рдЕрдВрджрд░ рдмреИрдЪ рдкреНрд░реЛрд╕реЗрд╕рд┐рдВрдЧ рдХреЗ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреА рдХрдореА рдХреЛ рдЫрд┐рдкрд╛ рд╕рдХрддреЗ рд╣реИрдВ:

interface UserRemoteApi {
   fun getUserById ( id : UserReference ) : UserRemote
   fun getUsersByIds ( id : Set < UserReference > ) : Set < UserRemote > =
     id . parallelStream ()
       . map { getUserById ( it ) } . collect ( toSet ())
   fun getUsersByIds ( id : List < UserReference > ) : List < UserRemote > =
     id . parallelStream ()
       . map { getUserById ( it ) } . collect ( toList ())
}


рдЗрд╕рд╕реЗ рдпрд╣ рд╕рдордЭ рдореЗрдВ рдЖрддрд╛ рд╣реИ рдХрд┐ рднрд╡рд┐рд╖реНрдп рдХреЗ рд╕рдВрд╕реНрдХрд░рдгреЛрдВ рдореЗрдВ рдмреИрдЪ рдкреНрд░реЛрд╕реЗрд╕рд┐рдВрдЧ рджрд┐рдЦрд╛рдИ рджреЗрдЧреА, рдРрд╕реА рдЖрд╢рд╛ рд╣реИред

рдкреЗрд╢реЗрд╡рд░реЛрдВ:

  1. рд╕рдорд╡рд░реНрддреА рд╕рдВрджреЗрд╢ рдкреНрд░рд╕рдВрд╕реНрдХрд░рдг рдХрд╛ рдЖрд╕рд╛рди рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрдиред
  2. рдЕрдЪреНрдЫрд╛ рд╕реНрдХреЗрд▓реЗрдмрд┐рд▓рд┐рдЯреАред

рд╡рд┐рдкрдХреНрд╖:

  1. рд╡рд┐рднрд┐рдиреНрди рд╕реЗрд╡рд╛рдУрдВ рдХреЗ рд▓рд┐рдП рд╕рдорд╛рдирд╛рдВрддрд░ рдкреНрд░рд╕рдВрд╕реНрдХрд░рдг рдЕрдиреБрд░реЛрдзреЛрдВ рдореЗрдВ рдЙрдирдХреЗ рдкреНрд░рд╕рдВрд╕реНрдХрд░рдг рд╕реЗ рдбреЗрдЯрд╛ рдХреА рдкреНрд░рд╛рдкреНрддрд┐ рдХреЛ рдЕрд▓рдЧ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред
  2. рддреГрддреАрдп-рдкрдХреНрд╖ рд╕реЗрд╡рд╛рдУрдВ рдкрд░ рдмрдврд╝рд╛ рд╣реБрдЖ рднрд╛рд░ред

рдпрд╣ рджреЗрдЦрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ рдХрд┐ рдкреНрд░рдпреЛрдЬреНрдпрддрд╛ рдХрд╛ рджрд╛рдпрд░рд╛ рд▓рдЧрднрдЧ рднреЛрд▓реЗ рджреГрд╖реНрдЯрд┐рдХреЛрдг рдХреЗ рд╕рдорд╛рди рд╣реИред рдпрджрд┐ рдЖрдк рджреВрд╕рд░реЛрдВ рдХреА рдмреЗрд░рд╣рдо рд╢реЛрд╖рдг рдХреЗ рдХрд╛рд░рдг рдХрдИ рдмрд╛рд░ рдЕрдкрдиреА рд╕реЗрд╡рд╛ рдХреЗ рдкреНрд░рджрд░реНрд╢рди рдХреЛ рдмрдврд╝рд╛рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ рддреЛ рд╕рдорд╛рдирд╛рдВрддрд░ рдХреНрд╡реЗрд░реА рдкрджреНрдзрддрд┐ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рд╕рдордЭ рдореЗрдВ рдЖрддрд╛ рд╣реИред рд╣рдорд╛рд░реЗ рдЙрджрд╛рд╣рд░рдг рдореЗрдВ, рдЙрддреНрдкрд╛рджрдХрддрд╛ 2.5 рдЧреБрдирд╛ рдмрдврд╝ рдЧрдИ, рд▓реЗрдХрд┐рди рдпрд╣ рд╕реНрдкрд╖реНрдЯ рд░реВрдк рд╕реЗ рдкрд░реНрдпрд╛рдкреНрдд рдирд╣реАрдВ рд╣реИред

рдХреИрд╢рд┐рдВрдЧ


рдЖрдк рдмрд╛рд╣рд░реА рд╕реЗрд╡рд╛рдУрдВ рдХреЗ рд▓рд┐рдП рдЬреЗрдкреАрдП рд╢реИрд▓реА рдХреА рдХреИрд╢рд┐рдВрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдЕрд░реНрдерд╛рддреН, рдкреНрд░рд╛рдкреНрдд рд╡рд╕реНрддреБрдУрдВ рдХреЛ рд╕рддреНрд░ рдХреЗ рднреАрддрд░ рд╕реНрдЯреЛрд░ рдХрд░реЗрдВ рддрд╛рдХрд┐ рдЙрдиреНрд╣реЗрдВ рдлрд┐рд░ рд╕реЗ рдкреНрд░рд╛рдкреНрдд рди рдХрд░реЗрдВ (рдмреИрдЪ рдкреНрд░рд╕рдВрд╕реНрдХрд░рдг рдХреЗ рджреМрд░рд╛рди)ред рдЖрдк рдЗрди рдХреИрд╢ рдХреЛ рд╕реНрд╡рдпрдВ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдЖрдк рд╕реНрдкреНрд░рд┐рдВрдЧ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рдЗрд╕рдХреЗ рд╕рд╛рде, рдЖрдк рд╣рдореЗрд╢рд╛ рддреИрдпрд╛рд░ рдХреИрд╢ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдЬреИрд╕реЗ рдПрд╣рдЪреИрдЪ рдореИрдиреНрдпреБрдЕрд▓ рд░реВрдк рд╕реЗред

рд╕рд╛рдорд╛рдиреНрдп рд╕рдорд╕реНрдпрд╛ рдЗрд╕ рддрдереНрдп рд╕реЗ рд╕рдВрдмрдВрдзрд┐рдд рд╣реЛрдЧреА рдХрд┐ рд╣рд┐рдЯ рд╣реЛрдиреЗ рдкрд░ рд╣реА рдХреИрд╢ рд╕реЗ рдЕрдЪреНрдЫрд╛ рдЕрд░реНрде рд╣реИред рд╣рдорд╛рд░реЗ рдорд╛рдорд▓реЗ рдореЗрдВ, рд▓реЗрдЦрдХ рдХреЗ рдХреНрд╖реЗрддреНрд░ рдкрд░ рд╣рд┐рдЯ (рдХрд╣рддреЗ рд╣реИрдВ, 50%) рдмрд╣реБрдд рд╕рдВрднрд╛рд╡рдирд╛ рд╣реИ, рдФрд░ рдлрд╛рдЗрд▓реЛрдВ рдкрд░ рдХреЛрдИ рд╣рд┐рдЯ рдирд╣реАрдВ рд╣реЛрдЧреАред рдпрд╣ рджреГрд╖реНрдЯрд┐рдХреЛрдг рдХреБрдЫ рд╕реБрдзрд╛рд░ рд▓рд╛рдПрдЧрд╛, рд▓реЗрдХрд┐рди рдкреНрд░рджрд░реНрд╢рди рдореМрд▓рд┐рдХ рд░реВрдк рд╕реЗ рдирд╣реАрдВ рдмрджрд▓реЗрдЧрд╛ (рдФрд░ рд╣рдореЗрдВ рдПрдХ рд╕рдлрд▓рддрд╛ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ)ред

рдШреБрд╕рдкреИрда (рд▓рдВрдмреЗ) рдХреИрд╢ рдореЗрдВ рдЬрдЯрд┐рд▓ рдЕрдорд╛рдиреНрдп рддрд░реНрдХ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИред рд╕рд╛рдорд╛рдиреНрдп рддреМрд░ рдкрд░, рдмрд╛рдж рдореЗрдВ рдЖрдк рдЗрд╕ рдмрд┐рдВрджреБ рдкрд░ рдкрд╣реБрдВрдЪ рдЬрд╛рддреЗ рд╣реИрдВ рдХрд┐ рдЖрдк рдЪреМрд░рд╛рд╣реЗ рд╡рд╛рд▓реЗ рдХреИрд╢ рдХреЗ рд╕рд╛рде рдкреНрд░рджрд░реНрд╢рди рдХреА рд╕рдорд╕реНрдпрд╛рдУрдВ рдХреЛ рд╣рд▓ рдХрд░реЗрдВрдЧреЗ, рдмреЗрд╣рддрд░ред

рдкреЗрд╢реЗрд╡рд░реЛрдВ:

  1. рдХреЛрдб рдХреЛ рдмрджрд▓реЗ рдмрд┐рдирд╛ рдХреИрд╢рд┐рдВрдЧ рд▓рд╛рдЧреВ рдХрд░реЗрдВред
  2. рдкреНрд░рджрд░реНрд╢рди рдХрдИ рдмрд╛рд░ (рдХреБрдЫ рдорд╛рдорд▓реЛрдВ рдореЗрдВ) рдмрдврд╝рддрд╛ рд╣реИред

рд╡рд┐рдкрдХреНрд╖:

  1. рдЕрдиреБрдЪрд┐рдд рддрд░реАрдХреЗ рд╕реЗ рдЙрдкрдпреЛрдЧ рдХрд┐рдП рдЬрд╛рдиреЗ рдкрд░ рдкреНрд░рджрд░реНрд╢рди рдореЗрдВ рдЧрд┐рд░рд╛рд╡рдЯ рдХреА рд╕рдВрднрд╛рд╡рдирд╛ред
  2. рдмрдбрд╝реЗ рдореЗрдореЛрд░реА рдУрд╡рд░рд╣реЗрдб, рд╡рд┐рд╢реЗрд╖ рд░реВрдк рд╕реЗ рд▓рдВрдмреЗ рдХреИрд╢ рдХреЗ рд╕рд╛рдеред
  3. рдЬрдЯрд┐рд▓ рдЕрдорд╛рдиреНрдпрдХрд░рдг, рддреНрд░реБрдЯрд┐рдпрд╛рдВ рдЬрд┐рд╕рдореЗрдВ рд░рдирдЯрд╛рдЗрдо рдореЗрдВ рдореБрд╢реНрдХрд┐рд▓ рд╕рдорд╕реНрдпрд╛рдПрдВ рдЖрдПрдВрдЧреАред

рдмрд╣реБрдд рдмрд╛рд░, рдХреИрд╢ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХреЗрд╡рд▓ рдбрд┐рдЬрд╛рдЗрди рдореБрджреНрджреЛрдВ рдХреЛ рдЬрд▓реНрджреА рд╕реЗ рдкреИрдЪ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдЗрд╕рдХрд╛ рдорддрд▓рдм рдпрд╣ рдирд╣реАрдВ рд╣реИ рдХрд┐ рдЙрдиреНрд╣реЗрдВ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИред рд╣рд╛рд▓рд╛рдВрдХрд┐, рдЙрдиреНрд╣реЗрдВ рд╕рд╛рд╡рдзрд╛рдиреА рд╕реЗ рд╡реНрдпрд╡рд╣рд╛рд░ рдХрд░рдирд╛ рдФрд░ рдкрд░рд┐рдгрд╛рдореА рдкреНрд░рджрд░реНрд╢рди рд▓рд╛рдн рдХрд╛ рдкрд╣рд▓реЗ рдореВрд▓реНрдпрд╛рдВрдХрди рдХрд░рдирд╛ рд╣рдореЗрд╢рд╛ рд╕рд╛рд░реНрдердХ рд╣реЛрддрд╛ рд╣реИ, рдФрд░ рдЙрд╕рдХреЗ рдмрд╛рдж рд╣реА рдХреЛрдИ рдирд┐рд░реНрдгрдп рд▓реЗрдВред

рд╣рдорд╛рд░реЗ рдЙрджрд╛рд╣рд░рдг рдореЗрдВ, рдХреИрд╢ рдореЗрдВ рд▓рдЧрднрдЧ 25% рдХреА рдкреНрд░рджрд░реНрд╢рди рд╡реГрджреНрдзрд┐ рд╣реЛрдЧреАред рдЗрд╕реА рд╕рдордп, рдХреИрд╢ рдореЗрдВ рдмрд╣реБрдд рд╕рд╛рд░реЗ рдиреБрдХрд╕рд╛рди рд╣реИрдВ, рдЗрд╕рд▓рд┐рдП рдореИрдВ рдпрд╣рд╛рдВ рдЙрдирдХрд╛ рдЙрдкрдпреЛрдЧ рдирд╣реАрдВ рдХрд░реВрдВрдЧрд╛ред

рдкрд░рд┐рдгрд╛рдо


рдЗрд╕рд▓рд┐рдП, рд╣рдордиреЗ рдПрдХ рдРрд╕реА рд╕реЗрд╡рд╛ рдХреЗ рдЕрдиреБрднрд╡рд╣реАрди рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреЛ рджреЗрдЦрд╛ рдЬреЛ рдмреИрдЪ рдкреНрд░рд╕рдВрд╕реНрдХрд░рдг рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИ, рдФрд░ рдЗрд╕реЗ рддреЗрдЬ рдХрд░рдиреЗ рдХреЗ рдХреБрдЫ рд╕рд░рд▓ рддрд░реАрдХреЗред

рдЗрди рд╕рднреА рддрд░реАрдХреЛрдВ рдХрд╛ рдореБрдЦреНрдп рд▓рд╛рдн рд╕рд╛рджрдЧреА рд╣реИ, рдЬрд┐рд╕рдореЗрдВ рд╕реЗ рдХрдИ рд╕реБрдЦрдж рдкрд░рд┐рдгрд╛рдо рд╣реИрдВред

рдЗрди рддрд░реАрдХреЛрдВ рдХреЗ рд╕рд╛рде рдПрдХ рдЖрдо рд╕рдорд╕реНрдпрд╛ рдЦрд░рд╛рдм рдкреНрд░рджрд░реНрд╢рди рд╣реИ, рдореБрдЦреНрдп рд░реВрдк рд╕реЗ рдкреИрдХреЗрдЯ рдЖрдХрд╛рд░ рдХреЗ рдХрд╛рд░рдгред рдЗрд╕рд▓рд┐рдП, рдпрджрд┐ рдпреЗ рд╕рдорд╛рдзрд╛рди рдЖрдкрдХреЛ рд╕реВрдЯ рдирд╣реАрдВ рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рдпрд╣ рдЕрдзрд┐рдХ рдХрдЯреНрдЯрд░рдкрдВрдереА рддрд░реАрдХреЛрдВ рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд░рдиреЗ рдХреЗ рд▓рд╛рдпрдХ рд╣реИред

рджреЛ рдореБрдЦреНрдп рдХреНрд╖реЗрддреНрд░ рд╣реИрдВ рдЬрд┐рдирдореЗрдВ рдЖрдк рд╕рдорд╛рдзрд╛рди рдЦреЛрдЬ рд╕рдХрддреЗ рд╣реИрдВ:

  • рдбреЗрдЯрд╛ рдХреЗ рд╕рд╛рде рдЕрддреБрд▓реНрдпрдХрд╛рд▓рд┐рдХ рдХрд╛рдо (рдПрдХ рдкреНрд░рддрд┐рдорд╛рди рдмрджрд▓рд╛рд╡ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рдЗрд╕рд▓рд┐рдП, рдЗрд╕ рд▓реЗрдЦ рдкрд░ рд╡рд┐рдЪрд╛рд░ рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ)
  • рддреБрд▓реНрдпрдХрд╛рд▓рд┐рдХ рдкреНрд░рд╕рдВрд╕реНрдХрд░рдг рдХреЛ рдмрдирд╛рдП рд░рдЦрддреЗ рд╣реБрдП рдкреИрдХ рдХрд╛ рдЗрдЬрд╝рд╛рдлрд╝рд╛ред

рдмрдВрдбрд▓реЛрдВ рдХрд╛ рдЗрдЬрд╝рд╛рдлрд╝рд╛ рдХреЛрдб рдХреЛ рд╕рдордХрд╛рд▓рд┐рдХ рд░рдЦрддреЗ рд╣реБрдП рдмрд╛рд╣рд░реА рдХреЙрд▓ рдХреА рд╕рдВрдЦреНрдпрд╛ рдХреЛ рдмрд╣реБрдд рдХрдо рдХрд░ рджреЗрдЧрд╛ред рд▓реЗрдЦ рдХрд╛ рдЕрдЧрд▓рд╛ рднрд╛рдЧ рдЗрд╕ рд╡рд┐рд╖рдп рдХреЗ рд▓рд┐рдП рд╕рдорд░реНрдкрд┐рдд рд╣реЛрдЧрд╛ред

Source: https://habr.com/ru/post/hi460291/


All Articles