
рдпрд╣ рд▓реЗрдЦ
"рдЕрдиреБрд░реЛрдзреЛрдВ рдФрд░ рдЙрдирдХреЗ рд╕рдорд╛рдзрд╛рди рдХреЗ рдмреИрдЪ рдкреНрд░рд╕рдВрд╕реНрдХрд░рдг рдХреА рд╕рдорд╕реНрдпрд╛рдПрдВ" рдХреА рдирд┐рд░рдВрддрд░рддрд╛ рд╣реИред рдпрд╣ рдЕрдиреБрд╢рдВрд╕рд╛ рдХреА рдЬрд╛рддреА рд╣реИ рдХрд┐ рдЖрдк рдкрд╣рд▓реЗ рднрд╛рдЧ рдХреЗ рд╕рд╛рде рдЦреБрдж рдХреЛ рдкрд░рд┐рдЪрд┐рдд рдХрд░реЗрдВ, рдХреНрдпреЛрдВрдХрд┐ рдпрд╣ рд╕рдорд╕реНрдпрд╛ рдХрд╛ рд╕рд╛рд░ рдФрд░ рдЗрд╕рдХреЗ рд╕рдорд╛рдзрд╛рди рдХреЗ рд▓рд┐рдП рдХреБрдЫ рджреГрд╖реНрдЯрд┐рдХреЛрдгреЛрдВ рдХрд╛ рд╡рд┐рд╕реНрддрд╛рд░ рд╕реЗ рд╡рд░реНрдгрди рдХрд░рддрд╛ рд╣реИред рдпрд╣рд╛рдВ рд╣рдо рдЕрдиреНрдп рддрд░реАрдХреЛрдВ рдХреЛ рджреЗрдЦрддреЗ рд╣реИрдВред
рдХрд╛рд░реНрдп рдХреА рд╕рдВрдХреНрд╖рд┐рдкреНрдд рдкреБрдирд░рд╛рд╡реГрддреНрддрд┐
рдкреНрд░рддрд┐рднрд╛рдЧрд┐рдпреЛрдВ рдХреЗ рдкреВрд░реНрд╡рдирд┐рд░реНрдзрд╛рд░рд┐рдд рд╕реЗрдЯ рдХреЗ рд╕рд╛рде рджрд╕реНрддрд╛рд╡реЗрдЬрд╝ рдХреЛ рд╕рдордиреНрд╡рдпрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдЪреИрдЯ рд╣реИред рд╕рдВрджреЗрд╢реЛрдВ рдореЗрдВ рдкрд╛рда рдФрд░ рдлрд╛рдЗрд▓реЗрдВ рд╣реЛрддреА рд╣реИрдВред рдФрд░, рдирд┐рдпрдорд┐рдд рдЪреИрдЯ рдХреЗ рд░реВрдк рдореЗрдВ, рд╕рдВрджреЗрд╢ рдЙрддреНрддрд░ рдФрд░ рдЖрдЧреЗ рд╣реЛ рд╕рдХрддреЗ рд╣реИрдВред
рд╕рдВрджреЗрд╢ рдореЙрдбрд▓ рдЪреИрдЯ рдХрд░реЗрдВ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
)
рдирд┐рд░реНрднрд░рддрд╛ рдЗрдВрдЬреЗрдХреНрд╢рди рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ, рд╣рдо рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдмрд╛рд╣рд░реА рд╕реЗрд╡рд╛рдУрдВ рдХреЛ рд▓рд╛рдЧреВ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ: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 >
}
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 >
}
рд╣рдореЗрдВ рдПрдХ REST рдирд┐рдпрдВрддреНрд░рдХ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ:
interface ChatRestApi {
fun getLast ( n : Int ) : List < ChatMessageUI >
}
рдЬрд╣рд╛рдВ:/** */
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
)
рдкрд┐рдЫрд▓реЗ рднрд╛рдЧ рдореЗрдВ, рд╣рдордиреЗ рдмреИрдЪ рдкреНрд░рд╕рдВрд╕реНрдХрд░рдг рдФрд░ рдЗрд╕реЗ рдЧрддрд┐ рджреЗрдиреЗ рдХреЗ рдХрдИ рддрд░реАрдХреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реБрдП рдПрдХ рд╕реЗрд╡рд╛ рдХреЗ рдЕрдиреБрднрд╡рд╣реАрди рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреЛ рджреЗрдЦрд╛ред рдпреЗ рд╡рд┐рдзрд┐рдпрд╛рдВ рдмрд╣реБрдд рд╕рд░рд▓ рд╣реИрдВ, рд▓реЗрдХрд┐рди рдЙрдирдХрд╛ рдЖрд╡реЗрджрди рдкрд░реНрдпрд╛рдкреНрдд рд░реВрдк рд╕реЗ рдЕрдЪреНрдЫрд╛ рдкреНрд░рджрд░реНрд╢рди рдкреНрд░рджрд╛рди рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИред
рдкреИрдХреЗрдЬ рдмрдврд╝рд╛рдПрдВ
рднреЛрд▓реА рд╕рдорд╛рдзрд╛рдиреЛрдВ рдХреА рдореБрдЦреНрдп рд╕рдорд╕реНрдпрд╛ рд╕рдВрдХреБрд▓ рдХреЗ рдЫреЛрдЯреЗ рдЖрдХрд╛рд░ рдХреА рдереАред
рдмрдбрд╝реЗ рдкреИрдХреЗрдЯ рдореЗрдВ рд╕рдореВрд╣ рдХреЙрд▓ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдЖрдкрдХреЛ рдХрд┐рд╕реА рддрд░рд╣ рдЕрдиреБрд░реЛрдзреЛрдВ рдХреЛ рдЬрдорд╛ рдХрд░рдирд╛ рд╣реЛрдЧрд╛ред рдпрд╣ рд▓рд╛рдЗрди рдЕрдиреБрд░реЛрдзреЛрдВ рдХреЗ рд╕рдВрдЪрдп рдХрд╛ рдорддрд▓рдм рдирд╣реАрдВ рд╣реИ:
author = userRepository . getUserById ( author ) . toFrontReference () ,
рдЕрдм рд╣рдорд╛рд░реЗ рд░рдирдЯрд╛рдЗрдо рдореЗрдВ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛рдУрдВ рдХреА рд╕реВрдЪреА рдХреЛ рд╕рдВрдЧреНрд░рд╣реАрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХреЛрдИ рд╡рд┐рд╢реЗрд╖ рд╕реНрдерд╛рди рдирд╣реАрдВ рд╣реИ - рдпрд╣ рдзреАрд░реЗ-рдзреАрд░реЗ рдмрди рд░рд╣рд╛ рд╣реИред рдЗрд╕реЗ рдмрджрд▓рдирд╛ рд╣реЛрдЧрд╛ред
рдкрд╣рд▓реЗ рдЖрдкрдХреЛ ChatMessage.toFrontModel рд╡рд┐рдзрд┐ рдореЗрдВ рдорд╛рдирдЪрд┐рддреНрд░рдг рд╕реЗ рдбреЗрдЯрд╛ рдЕрдзрд┐рдЧреНрд░рд╣рдг рдХреЗ рддрд░реНрдХ рдХреЛ рдЕрд▓рдЧ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ:
private fun ChatMessage . toFrontModel (
getUser : ( UserReference ) -> UserRemote ,
getFile : ( FileReference ) -> FileHeadRemote ,
serializeMessage : ( ChatMessage ) -> ChatMessageUI
) : ChatMessageUI =
ChatMessageUI (
id = id ?: throw IllegalStateException ( " $ this must be persisted" ) ,
author = getUser ( author ) . toFrontReference () ,
message = message ,
files = files ?. let {
it . map ( getFile ) . map { it . toFrontReference () }
} ?: listOf () ,
forwardFrom = forwardFrom ?. let ( serializeMessage ) ,
replyTo = replyTo ?. let ( serializeMessage )
)
рдпрд╣ рдкрддрд╛ рдЪрд▓рд╛ рд╣реИ рдХрд┐ рдпрд╣ рдлрд╝рдВрдХреНрд╢рди рдХреЗрд╡рд▓ рддреАрди рдмрд╛рд╣рд░реА рдХрд╛рд░реНрдпреЛрдВ рдкрд░ рдирд┐рд░реНрднрд░ рдХрд░рддрд╛ рд╣реИ (рдФрд░ рд╕рдВрдкреВрд░реНрдг рдХрдХреНрд╖рд╛рдУрдВ рдкрд░ рдирд╣реАрдВ, рдЬреИрд╕рд╛ рдХрд┐ рдпрд╣ рд╢реБрд░реБрдЖрдд рдореЗрдВ рдерд╛)ред
рдЗрд╕ рддрд░рд╣ рдХреА рдмрд╣рд╛рд▓реА рдХреЗ рдмрд╛рдж, рдлрд╝рдВрдХреНрд╢рди рдХрд╛ рд╢рд░реАрд░ рдХрдо рд╕реНрдкрд╖реНрдЯ рдирд╣реАрдВ рд╣реЛ рдЧрдпрд╛, рдФрд░ рдЕрдиреБрдмрдВрдз рдХрдард┐рди рд╣реЛ рдЧрдпрд╛ (рдЗрд╕рдореЗрдВ рдкреЗрд╢реЗрд╡рд░реЛрдВ рдФрд░ рд╡рд┐рдкрдХреНрд╖ рджреЛрдиреЛрдВ рд╢рд╛рдорд┐рд▓ рд╣реИрдВ)ред
рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ, рдЖрдк рдЕрдиреБрдмрдВрдз рдХреА рдРрд╕реА рд╕рдВрдХреАрд░реНрдгрддрд╛ рдирд╣реАрдВ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдФрд░ рдЗрдВрдЯрд░рдлреЗрд╕ рдкрд░ рдирд┐рд░реНрднрд░рддрд╛ рдЫреЛрдбрд╝ рд╕рдХрддреЗ рд╣реИрдВред рдореБрдЦреНрдп рдмрд╛рдд рдпрд╣ рд╣реИ рдХрд┐ рдирд┐рд╢реНрдЪрд┐рдд рд░реВрдк рд╕реЗ рдЙрдирдореЗрдВ рдмрд╣реБрдд рдХреБрдЫ рдирд╣реАрдВ рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рд╣рдореЗрдВ рд╡реИрдХрд▓реНрдкрд┐рдХ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрдЧреАред
рдЪреВрдВрдХрд┐ serializeMessage рдлрд╝рдВрдХреНрд╢рди рдПрдХ рдкреБрдирд░рд╛рд╡рд░реНрддреА рдлрд╝рдВрдХреНрд╢рди рдХреЗ рд╕рдорд╛рди рд╣реИ, рдЗрд╕рд▓рд┐рдП рдЗрд╕реЗ рд░рд┐рдлреИрдХреНрдЯрд░рд┐рдВрдЧ рдХреЗ рдкрд╣рд▓реЗ рдЪрд░рдг рдореЗрдВ рдПрдХ рд╕реНрдкрд╖реНрдЯ рдкреБрдирд░рд╛рд╡реГрддреНрддрд┐ рдХреЗ рд░реВрдк рдореЗрдВ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ:
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 () }
рдореИрдВрдиреЗ toFrontModel рдореЗрдердб рдХреЗ рд▓рд┐рдП рдПрдХ рд╕реНрдЯрдм рдмрдирд╛рдпрд╛, рдЬреЛ рдЕрдм рддрдХ рдареАрдХ рд╡реИрд╕реЗ рд╣реА рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ рдЬреИрд╕реЗ рд╣рдорд╛рд░реЗ рдкрд╣рд▓реЗ рднреЛрд▓реЗ-рднрд╛рд▓реЗ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди (рддреАрдиреЛрдВ рдмрд╛рд╣рд░реА рдХрд╛рд░реНрдпреЛрдВ рдХрд╛ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рд╕рдорд╛рди рд░рд╣рддрд╛ рд╣реИ)ред
private fun ChatMessage . toFrontModel () : ChatMessageUI =
toFrontModel (
getUser = userRepository ::getUserById ,
getFile = fileRepository ::getHeadById ,
serializeMessage = { it . toFrontModel () }
)
рд▓реЗрдХрд┐рди рд╣рдореЗрдВ getUser, getFile, рдФрд░ serializeMessage рдлрд╝рдВрдХреНрд╢рди рдХреЛ рдХреБрд╢рд▓рддрд╛рдкреВрд░реНрд╡рдХ рдХрд╛рд░реНрдп рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рдЕрд░реНрдерд╛рдд, рд╕рд╣реА рдЖрдХрд╛рд░ рдХреЗ рдкреИрдХреЗрдЯ рдореЗрдВ рдЙрдЪрд┐рдд рд╕реЗрд╡рд╛рдУрдВ рдХреЗ рд▓рд┐рдП рдЕрдиреБрд░реЛрдз рднреЗрдЬреЗрдВ (рд╕реИрджреНрдзрд╛рдВрддрд┐рдХ рд░реВрдк рд╕реЗ, рдпрд╣ рдЖрдХрд╛рд░ рдкреНрд░рддреНрдпреЗрдХ рд╕реЗрд╡рд╛ рдХреЗ рд▓рд┐рдП рдЕрд▓рдЧ рд╣реЛ рд╕рдХрддрд╛ рд╣реИ) рдпрд╛ рдЖрдо рддреМрд░ рдкрд░ рдкреНрд░рддрд┐ рд╕реЗрд╡рд╛ рдПрдХ рдЕрд╕реАрдорд┐рдд рдЕрдиреБрд░реЛрдз рдХреА рдЕрдиреБрдорддрд┐ рд╣реИред
рдЗрд╕ рд╕рдореВрд╣реАрдХрд░рдг рдХреЛ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХрд╛ рд╕рдмрд╕реЗ рдЖрд╕рд╛рди рддрд░реАрдХрд╛ рд╣реИ рдпрджрд┐ рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдкреНрд░рд╕рдВрд╕реНрдХрд░рдг рд╢реБрд░реВ рдХрд░рдиреЗ рд╕реЗ рдкрд╣рд▓реЗ рд╕рднреА рдЖрд╡рд╢реНрдпрдХ рдкреНрд░рд╢реНрди рд╣реИрдВред рдРрд╕рд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, toFrontModel рдкрд░ рдХреЙрд▓ рдХрд░рдиреЗ рд╕реЗ рдкрд╣рд▓реЗ, рд╕рднреА рдЖрд╡рд╢реНрдпрдХ рд▓рд┐рдВрдХ рдПрдХрддреНрд░ рдХрд░реЗрдВ, рдмреИрдЪ рдкреНрд░реЛрд╕реЗрд╕рд┐рдВрдЧ рдХрд░реЗрдВ, рдФрд░ рдлрд┐рд░ рдкрд░рд┐рдгрд╛рдо рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВред
рдЖрдк рдЕрдиреБрд░реЛрдзреЛрдВ рдХреЗ рд╕рдВрдЪрдп рдФрд░ рдЙрдирдХреЗ рдХреНрд░рдорд┐рдХ рдирд┐рд╖реНрдкрд╛рджрди рдХреЗ рд╕рд╛рде рдпреЛрдЬрдирд╛ рднреА рдЖрдЬрд╝рдорд╛ рд╕рдХрддреЗ рд╣реИрдВред рд╣рд╛рд▓рд╛рдВрдХрд┐, рдРрд╕реА рдпреЛрдЬрдирд╛рдУрдВ рдХреЗ рд▓рд┐рдП рдЕрддреБрд▓реНрдпрдХрд╛рд▓рд┐рдХ рдирд┐рд╖реНрдкрд╛рджрди рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрдЧреА, рд▓реЗрдХрд┐рди рдЕрдм рд╣рдо рд╕рдордХрд╛рд▓рд┐рдХ рд▓реЛрдЧреЛрдВ рдкрд░ рдзреНрдпрд╛рди рдХреЗрдВрджреНрд░рд┐рдд рдХрд░реЗрдВрдЧреЗред
рдЗрд╕рд▓рд┐рдП, рдмреИрдЪ рдкреНрд░реЛрд╕реЗрд╕рд┐рдВрдЧ рдХрд╛ рдЙрдкрдпреЛрдЧ рд╢реБрд░реВ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдПрдХ рдпрд╛ рджреВрд╕рд░реЗ рддрд░реАрдХреЗ рд╕реЗ рд╣рдореЗрдВ рдкрд╣рд▓реЗ рд╕реЗ рдЕрдзрд┐рдХ рд╕реЗ рдЕрдзрд┐рдХ рдЕрдиреБрд░реЛрдзреЛрдВ рдХрд╛ рдкрддрд╛ рд▓рдЧрд╛рдирд╛ рд╣реЛрдЧрд╛ (рдЕрдзрд┐рдорд╛рдирддрдГ рд╕рднреА) рдЬреЛ рд╣рдореЗрдВ рдмрдирд╛рдиреЗ рд╣реЛрдВрдЧреЗред рдЕрдЧрд░ рд╣рдо REST рдХрдВрдЯреНрд░реЛрд▓рд░ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдмрд╛рдд рдХрд░ рд░рд╣реЗ рд╣реИрдВ, рддреЛ рдкреВрд░реЗ рд╕рддреНрд░ рдореЗрдВ рдкреНрд░рддреНрдпреЗрдХ рд╕реЗрд╡рд╛ рдХреЗ рд▓рд┐рдП рдЕрдиреБрд░реЛрдзреЛрдВ рдХреЛ рд╕рдВрдпреЛрдЬрд┐рдд рдХрд░рдирд╛ рдЕрдЪреНрдЫрд╛ рд╣реЛрдЧрд╛ред
рд╕рднреА рдХреЙрд▓ рд╕рдореВрд╣рдХреБрдЫ рд╕реНрдерд┐рддрд┐рдпреЛрдВ рдореЗрдВ, рд╕рддреНрд░ рдХреЗ рднреАрддрд░ рдЖрд╡рд╢реНрдпрдХ рд╕рднреА рдбреЗрдЯрд╛ рддреБрд░рдВрдд рдкреНрд░рд╛рдкреНрдд рдХрд┐рдП рдЬрд╛ рд╕рдХрддреЗ рд╣реИрдВ рдФрд░ рд╕рдВрд╕рд╛рдзрдиреЛрдВ рдХреЗ рд╕рд╛рде рдпрд╛ рддреЛ рдЕрдиреБрд░реЛрдз рдХреЗ рд╕рд░реНрдЬрдХ рд╕реЗ рдпрд╛ рдирд┐рд╖реНрдкрд╛рджрдХ рд╕реЗ рд╕рдорд╕реНрдпрд╛рдПрдВ рдкреИрджрд╛ рдирд╣реАрдВ рдХрд░реЗрдВрдЧреЗред рдЗрд╕ рдорд╛рдорд▓реЗ рдореЗрдВ, рд╣рдо рд╕реЗрд╡рд╛ рдХреЛ рдХреЙрд▓ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдкреИрдХреЗрдЯ рдХреЗ рдЖрдХрд╛рд░ рдХреЛ рд╕реАрдорд┐рдд рдирд╣реАрдВ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдФрд░ рддреБрд░рдВрдд рдПрдХ рд╣реА рдмрд╛рд░ рдореЗрдВ рд╕рднреА рдбреЗрдЯрд╛ рдкреНрд░рд╛рдкреНрдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред
рдПрдХ рдФрд░ рдзрд╛рд░рдгрд╛ рдЬреЛ рдЬреАрд╡рди рдХреЛ рдмрд╣реБрдд рдЖрд╕рд╛рди рдмрдирд╛рддреА рд╣реИ, рдпрд╣ рдорд╛рди рд▓реЗрдирд╛ рд╣реИ рдХрд┐ рд╕рд░реНрдЬрдХ рдХреЗ рдкрд╛рд╕ рд╕рднреА рдбреЗрдЯрд╛ рдХреЛ рд╕рдВрд╕рд╛рдзрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдкрд░реНрдпрд╛рдкреНрдд рд╕рдВрд╕рд╛рдзрди рд╣реИрдВред рдмрд╛рд╣рд░реА рд╕реЗрд╡рд╛рдУрдВ рдХреЗ рд▓рд┐рдП рдЕрдиреБрд░реЛрдз рд╕реАрдорд┐рдд рдкреИрдХреЗрдЬреЛрдВ рдореЗрдВ рднреА рднреЗрдЬреЗ рдЬрд╛ рд╕рдХрддреЗ рд╣реИрдВ, рдЕрдЧрд░ рдЙрдиреНрд╣реЗрдВ рдЗрд╕рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИред
рдЗрд╕ рдорд╛рдорд▓реЗ рдореЗрдВ рддрд░реНрдХ рдХрд╛ рд╕рд░рд▓реАрдХрд░рдг рдЪрд┐рдВрддрд╛ рдХрд░рддрд╛ рд╣реИ рдХрд┐ рдЬрд┐рди рд╕реНрдерд╛рдиреЛрдВ рдкрд░ рдбреЗрдЯрд╛ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рдЙрдирдХреА рддреБрд▓рдирд╛ рдХреЙрд▓ рдХреЗ рдкрд░рд┐рдгрд╛рдореЛрдВ рд╕реЗ рдХреИрд╕реЗ рдХреА рдЬрд╛рдПрдЧреАред рдпрджрд┐ рд╣рдо рдорд╛рдирддреЗ рд╣реИрдВ рдХрд┐ рд╕рд░реНрдЬрдХ рдХреЗ рд╕рдВрд╕рд╛рдзрди рдмрд╣реБрдд рд╕реАрдорд┐рдд рд╣реИрдВ, рдФрд░ рдПрдХ рд╣реА рд╕рдордп рдореЗрдВ рдмрд╛рд╣рд░реА рдХреЙрд▓ рдХреА рд╕рдВрдЦреНрдпрд╛ рдХреЛ рдХрдо рдХрд░рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рд╣рдореЗрдВ рдЧреНрд░рд╛рдл рдХреЗ рдЗрд╖реНрдЯрддрдо рдХрд╛рдЯрдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдХрдард┐рди рдХрд╛рдо рдорд┐рд▓рддрд╛ рд╣реИред рд╕рдмрд╕реЗ рдЕрдзрд┐рдХ рд╕рдВрднрд╛рд╡рдирд╛ рд╣реИ, рдЖрдкрдХреЛ рдмрд╕ рд╕рдВрд╕рд╛рдзрди рдЦрдкрдд рдХреЛ рдХрдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдкреНрд░рджрд░реНрд╢рди рдХрд╛ рддреНрдпрд╛рдЧ рдХрд░рдирд╛ рд╣реЛрдЧрд╛ред
рд╣рдо рд╡рд┐рдЪрд╛рд░ рдХрд░реЗрдВрдЧреЗ рдХрд┐ рд╡рд┐рд╢реЗрд╖ рд░реВрдк рд╕реЗ рд╣рдорд╛рд░реЗ рдбреЗрдореЛ рдкреНрд░реЛрдЬреЗрдХреНрдЯ рдореЗрдВ рд╕рд░реНрдЬрдХ рд╕рдВрд╕рд╛рдзрдиреЛрдВ рдореЗрдВ рд╡рд┐рд╢реЗрд╖ рд░реВрдк рд╕реЗ рд╕реАрдорд┐рдд рдирд╣реАрдВ рд╣реИ, рд╡рд╣ рд╕рднреА рдЖрд╡рд╢реНрдпрдХ рдбреЗрдЯрд╛ рдкреНрд░рд╛рдкреНрдд рдХрд░ рд╕рдХрддрд╛ рд╣реИ рдФрд░ рд╕рддреНрд░ рдХреЗ рдЕрдВрдд рддрдХ рдЗрд╕реЗ рд╕реНрдЯреЛрд░ рдХрд░ рд╕рдХрддрд╛ рд╣реИред рдпрджрд┐ рд╕рдВрд╕рд╛рдзрдиреЛрдВ рдХреА рд╕рдорд╕реНрдпрд╛рдПрдБ рд╣реИрдВ, рддреЛ рд╣рдо рд╕рд┐рд░реНрдл рдЫреЛрдЯреЗ рд╕реНрддрд░ рдкрд░ рдХрджрдо рд░рдЦреЗрдВрдЧреЗред
рдЪреВрдВрдХрд┐ рдореЗрд░реЗ рд╡реНрдпрд╡рд╣рд╛рд░ рдореЗрдВ рдЗрд╕ рддрд░рд╣ рдХрд╛ рджреГрд╖реНрдЯрд┐рдХреЛрдг рд╕рдмрд╕реЗ рдЕрдзрд┐рдХ рдорд╛рдВрдЧ рдореЗрдВ рд╣реИ, рдЗрд╕рд▓рд┐рдП рдЖрдЧреЗ рдХреЗ рдЙрджрд╛рд╣рд░рдг рдЗрд╕ рд╡рд┐рдХрд▓реНрдк рдХреА рдЪрд┐рдВрддрд╛ рдХрд░реЗрдВрдЧреЗред
рд╣рдо рдкреНрд░рд╢реНрдиреЛрдВ рдХреЗ рдмрдбрд╝реЗ рд╕реЗрдЯ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреЗ рдРрд╕реЗ рддрд░реАрдХреЛрдВ рдХреЛ рдЕрд▓рдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ:
- рд░рд┐рд╡рд░реНрд╕ рдЗрдВрдЬреАрдирд┐рдпрд░рд┐рдВрдЧ;
- рд╡реНрдпрд╡рд╕рд╛рдп рдХреЗ рдЖрдВрдХрдбрд╝реЗ;
- DDD рдХреА рд╢реИрд▓реА рдореЗрдВ рд╕рдореБрдЪреНрдЪрдп;
- рдкреНрд░реЙрдХреНрд╕реА рдФрд░ рдбрдмрд▓ рдХреЙрд▓ред
рдЖрдЗрдП рд╣рдорд╛рд░реА рдкрд░рд┐рдпреЛрдЬрдирд╛ рдХреЗ рдЙрджрд╛рд╣рд░рдг рдкрд░ рд╕рднреА рд╡рд┐рдХрд▓реНрдкреЛрдВ рдХреЛ рджреЗрдЦреЗрдВред
рд░рд┐рд╡рд░реНрд╕ рдЗрдВрдЬреАрдирд┐рдпрд░рд┐рдВрдЧ
рд╕рднреА рдЕрдиреБрд░реЛрдз рдПрдХрддреНрд░ рдХрд░реЗрдВрдЪреВрдБрдХрд┐ рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдЬрд╛рдирдХрд╛рд░реА рдПрдХрддреНрд░ рдХрд░рдиреЗ рдФрд░ рдЗрд╕реЗ рджреГрд╢реНрдпрдкрдЯрд▓ рдХреЗ рд▓рд┐рдП рдкрд░рд┐рд╡рд░реНрддрд┐рдд рдХрд░рдиреЗ рдореЗрдВ рд╢рд╛рдорд┐рд▓ рд╕рднреА рдХрд╛рд░реНрдпреЛрдВ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдХреЛрдб рд╣реИ, рд╣рдо рд░рд┐рд╡рд░реНрд╕ рдЗрдВрдЬреАрдирд┐рдпрд░рд┐рдВрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдФрд░ рдЗрд╕ рдХреЛрдб рд╕реЗ рд╣рдо рд╕рдордЭ рд╕рдХрддреЗ рд╣реИрдВ рдХрд┐ рдЕрдиреБрд░реЛрдз рдХреНрдпрд╛ рд╣реЛрдВрдЧреЗ:
class ChatRestController (
private val messageRepository : ChatMessageRepository ,
private val userRepository : UserRemoteApi ,
private val fileRepository : FileRemoteApi
) : ChatRestApi {
override fun getLast ( n : Int ) =
messageRepository . findLast ( n )
. let { messages ->
// , forward reply
val allMessages = messages . asSequence () . flatMap {
sequenceOf ( it , it . forwardFrom , it . replyTo ) . filterNotNull ()
} . toSet ()
val allUserReq = allMessages . map { it . author }
val allFileReq = allMessages . flatMap { it . files ?: listOf () } . toSet ()
рд╕рднреА рдЕрдиреБрд░реЛрдз рдПрдХрддреНрд░ рдХрд┐рдП рдЬрд╛рддреЗ рд╣реИрдВ, рдЕрдм рдЖрдкрдХреЛ рд╡рд╛рд╕реНрддрд╡рд┐рдХ рдмреИрдЪ рдкреНрд░рд╕рдВрд╕реНрдХрд░рдг рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред
AllUserReq рдФрд░ allFileReq рдХреЗ рд▓рд┐рдП, рд╣рдо рдмрд╛рд╣рд░реА рдкреНрд░рд╢реНрди рдмрдирд╛рддреЗ рд╣реИрдВ рдФрд░ рдЙрдиреНрд╣реЗрдВ рдЖрдИрдбреА рджреНрд╡рд╛рд░рд╛ рд╕рдореВрд╣рд┐рдд рдХрд░рддреЗ рд╣реИрдВред рдпрджрд┐ рдкреИрдХреЗрдЬ рдХреЗ рдЖрдХрд╛рд░ рдкрд░ рдХреЛрдИ рдкреНрд░рддрд┐рдмрдВрдз рдирд╣реАрдВ рд╣реИ, рддреЛ рдпрд╣ рдХреБрдЫ рдЗрд╕ рддрд░рд╣ рджрд┐рдЦрд╛рдИ рджреЗрдЧрд╛:
userRepository . getUsersByIds ( allMessages . map { it . author } . toSet ())
. associateBy { it . id } ::get
fileRepository . getHeadsByIds ( allMessages . flatMap { it . files ?: listOf () } . toSet ())
. associateBy { it . id } ::get
рдпрджрд┐ рдХреЛрдИ рдкреНрд░рддрд┐рдмрдВрдз рд╣реИ, рддреЛ рдХреЛрдб рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рд░реВрдк рд▓реЗрдЧрд╛:
val userApiChunkLimit = 100
allMessages . map { it . author } . asSequence () . distinct ()
. chunked ( userApiChunkLimit , userRepository ::getUsersByIds )
. flatten ()
. associateBy { it . id } ::get
рджреБрд░реНрднрд╛рдЧреНрдп рд╕реЗ, рд╕реНрдЯреНрд░реАрдо рдХреЗ рд╡рд┐рдкрд░реАрдд, рдЕрдиреБрдХреНрд░рдо рдЖрд╕рд╛рдиреА рд╕реЗ рдПрдХ рд╕рдорд╛рдирд╛рдВрддрд░ рдкреИрдХреЗрдЯ рдЕрдиреБрд░реЛрдз рдкрд░ рд╕реНрд╡рд┐рдЪ рдирд╣реАрдВ рдХрд░ рд╕рдХрддрд╛ рд╣реИред
рдпрджрд┐ рдЖрдк рдПрдХ рд╕рдорд╛рдирд╛рдВрддрд░ рдХреНрд╡реЗрд░реА рдХреЛ рдорд╛рдиреНрдп рдФрд░ рдЖрд╡рд╢реНрдпрдХ рдорд╛рдирддреЗ рд╣реИрдВ, рддреЛ рдЖрдк рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдпрд╣:
allMessages . map { it . author } . parallelStream () . distinct ()
. chunked ( userApiChunkLimit , userRepository ::getUsersByIds )
. flatten ()
. associateBy { it . id } ::get
рдпрд╣ рджреЗрдЦрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ рдХрд┐ рдХреБрдЫ рднреА рдмрд╣реБрдд рдХреБрдЫ рдирд╣реАрдВ рдмрджрд▓рд╛ рд╣реИред рдХреЛрдЯрд▓рд┐рди рдЬрд╛рджреВ рдХреА рдПрдХ рдирд┐рд╢реНрдЪрд┐рдд рдорд╛рддреНрд░рд╛ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рд╕реЗ рд╣рдореЗрдВ рдЗрд╕рдореЗрдВ рдорджрдж рдорд┐рд▓реА:
fun < T , R > Stream < out T >. chunked ( size : Int , transform : ( List < T > ) -> R ) : Stream < out R > =
batches ( this , size ) . map ( transform )
fun < T > Stream < out Collection < T >>. flatten () : Stream < T > =
flatMap { it . stream () }
fun < T , K > Stream < T >. associateBy ( keySelector : ( T ) -> K ) : Map < K , T > =
collect ( Collectors . toMap ( keySelector , { it } ))
рдЕрдм рд╕рдм рдХреБрдЫ рдПрдХ рд╕рд╛рде рд░рдЦрдирд╛ рдмрд╛рдХреА рд╣реИ:override fun getLast ( n : Int ) =
messageRepository . findLast ( n )
. let { messages ->
// , forward reply
val allMessages = messages . asSequence () . flatMap { message ->
sequenceOf ( message , message . forwardFrom , message . replyTo )
. filterNotNull ()
} . toSet ()
messages . map ( ValueHolder < ( ChatMessage ) -> ChatMessageUI > () . apply {
value = memoize { message : ChatMessage ->
message . toFrontModel (
// ,
getUser = allMessages . map { it . author } . parallelStream () . distinct ()
. chunked ( userApiChunkLimit , userRepository ::getUsersByIds )
. flatten ()
. associateBy { it . id } ::get . orThrow { IllegalArgumentException ( "User $ it" ) } ,
//
getFile = fileRepository . getHeadsByIds ( allMessages . flatMap { it . files ?: listOf () } . toSet ())
. associateBy { it . id } ::get . orThrow { IllegalArgumentException ( "File $ it" ) } ,
//
serializeMessage = value
)
}
} . value )
}
рд╕реНрдкрд╖реНрдЯреАрдХрд░рдг рдФрд░ рд╕рд░рд▓реАрдХрд░рдгрдкрд╣рд▓реА рдЪреАрдЬ рдЬреЛ рдирд┐рд╢реНрдЪрд┐рдд рд░реВрдк рд╕реЗ рдЖрдкрдХреА рдЖрдВрдЦ рдХреЛ рдкрдХрдбрд╝реЗрдЧреА рд╡рд╣ рд╣реИ рдореЗрдореЛрдЗрдЬрд╝ рдлрдВрдХреНрд╢рдиред рддрдереНрдп рдпрд╣ рд╣реИ рдХрд┐ serializeMessage рдлрд╝рдВрдХреНрд╢рди рд▓рдЧрднрдЧ рдирд┐рд╢реНрдЪрд┐рдд рд░реВрдк рд╕реЗ рдПрдХ рд╣реА рд╕рдВрджреЗрд╢реЛрдВ (рдЙрддреНрддрд░ рдФрд░ рдЖрдЧреЗ рдХреЗ рдХрд╛рд░рдг) рдХреЗ рд▓рд┐рдП рдХрдИ рдмрд╛рд░ рдХреЙрд▓ рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ред рдпрд╣ рд╕реНрдкрд╖реНрдЯ рдирд╣реАрдВ рд╣реИ рдХрд┐ рд╣рдореЗрдВ рдкреНрд░рддреНрдпреЗрдХ рдРрд╕реЗ рд╕рдВрджреЗрд╢ рдХреЗ рд▓рд┐рдП рдЕрд▓рдЧ рд╕реЗ toFrontModel рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдП (рдХреБрдЫ рдорд╛рдорд▓реЛрдВ рдореЗрдВ рдпрд╣ рдЖрд╡рд╢реНрдпрдХ рд╣реЛ рд╕рдХрддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рд╣рдорд╛рд░рд╛ рдирд╣реАрдВ)ред рдЗрд╕рд▓рд┐рдП, рдЖрдк serializeMessage рдлрд╝рдВрдХреНрд╢рди рдХреЗ рд▓рд┐рдП рдЬреНрдЮрд╛рдкрди рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рдпрд╣ рд▓рд╛рдЧреВ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдЗрд╕ рдкреНрд░рдХрд╛рд░ рд╣реИ:
fun < A , R > memoize ( func : ( A ) -> R ) = func as? Memoize2 ?: Memoize2 ( func )
class Memoize2 < A , R > ( val func : ( A ) -> R ) : ( A ) -> R , java . util . function . Function < A , R > {
private val cache = hashMapOf < A , R > ()
override fun invoke ( p1 : A ) = cache . getOrPut ( p1 , { func ( p1 ) } )
override fun apply ( t : A ) : R = invoke ( t )
}
рдЕрдЧрд▓рд╛, рд╣рдореЗрдВ рдПрдХ рд╕рдВрд╕реНрдорд░рдгрд┐рдд рдлрдВрдХреНрд╢рди рдХреНрд░рдордмрджреНрдзрддрд╛ рдХрд╛ рдирд┐рд░реНрдорд╛рдг рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рд╕рд╛рде рд╣реА рдЗрд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рдЗрд╕рдХреЗ рдЕрдВрджрд░ рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ред рдЕрдВрджрд░ рдлрд╝рдВрдХреНрд╢рди рдХреЗ рд╕рдорд╛рди рдЙрджрд╛рд╣рд░рдг рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рдорд╣рддреНрд╡рдкреВрд░реНрдг рд╣реИ, рдЕрдиреНрдпрдерд╛ рд╕рднреА рд╕рдВрд╕реНрдорд░рдг рдирд╛рд▓реА рдХреЗ рдиреАрдЪреЗ рдЬрд╛рдПрдВрдЧреЗред рдЗрд╕ рдЯрдХрд░рд╛рд╡ рдХреЛ рд╣рд▓ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдо ValueHolder рд╡рд░реНрдЧ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВ, рдЬреЛ рдХреЗрд╡рд▓ рдорд╛рди рдХреЗ рд▓рд┐рдП рдПрдХ рд╕рдВрджрд░реНрдн рд╕рдВрдЧреНрд░рд╣реАрдд рдХрд░рддрд╛ рд╣реИ (рдЖрдк рдЗрд╕рдХреЗ рдмрдЬрд╛рдп рдХреБрдЫ рдорд╛рдирдХ рд▓реЗ рд╕рдХрддреЗ рд╣реИрдВ, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, AtomicReference)ред рдкреБрдирд░рд╛рд╡реГрддреНрддрд┐ рдХреЗ рд▓рд┐рдП рд░рд┐рдХреЙрд░реНрдб рдХреЛ рдЫреЛрдЯрд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдЖрдк рдпрд╣ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ:
inline fun < A , R > recursiveMemoize ( crossinline func : ( A , ( A ) -> R ) -> R ) : ( A ) -> R =
ValueHolder < ( A ) -> R > () . apply {
value = memoize { a -> func ( a , value ) }
} . value
рдпрджрд┐ рдЖрдк рдкрд╣рд▓реА рдмрд╛рд░ рдЗрд╕ рддреАрд░ рдХреЗ рдирд╛рд░реЗ рдХреЛ рд╕рдордЭ рд╕рдХрддреЗ рд╣реИрдВ - рдмрдзрд╛рдИ рд╣реЛ, рддреЛ рдЖрдк рдПрдХ рдХрд╛рд░реНрдпрд╛рддреНрдордХ рдкреНрд░реЛрдЧреНрд░рд╛рдорд░ рд╣реИрдВ :-)
рдЕрдм рдХреЛрдб рдЗрд╕ рддрд░рд╣ рджрд┐рдЦреЗрдЧрд╛:
override fun getLast ( n : Int ) =
messageRepository . findLast ( n )
. let { messages ->
// , forward reply
val allMessages = messages . asSequence () . flatMap { message ->
sequenceOf ( message , message . forwardFrom , message . replyTo )
. filterNotNull ()
} . toSet ()
// ,
val getUser = allMessages . map { it . author } . parallelStream () . distinct ()
. chunked ( userApiChunkLimit , userRepository ::getUsersByIds )
. flatten ()
. associateBy { it . id } ::get . orThrow { IllegalArgumentException ( "User $ it " ) }
//
val getFile = fileRepository . getHeadsByIds ( allMessages . flatMap { it . files ?: listOf () } . toSet ())
. associateBy { it . id } ::get . orThrow { IllegalArgumentException ( "File $ it" ) }
messages . map ( recursiveMemoize { message , memoized : ( ChatMessage ) -> ChatMessageUI ->
message . toFrontModel (
getUser = getUser ,
getFile = getFile ,
//
serializeMessage = memoized
)
} )
рдЖрдк рдпрд╣ рднреА рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВ рдХрд┐ рдпрд╣ рдХреИрд╕реЗ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ:
/** [exception] , null */
fun < P , R > (( P ) -> R ? ) . orThrow ( exception : ( P ) -> Exception ) : ( P ) -> R =
{ p -> invoke ( p ) . let { it ?: throw exception ( p ) } }
рдпрджрд┐ рдмрд╛рд╣рд░реА рд╕реЗрд╡рд╛рдУрдВ рдореЗрдВ рд╣рдорд╛рд░реА рдЖрдИрдбреА рдкрд░ рдХреЛрдИ рдбреЗрдЯрд╛ рдирд╣реАрдВ рд╣реИ рдФрд░ рдЗрд╕реЗ рдХрд╛рдиреВрдиреА рд╕реНрдерд┐рддрд┐ рдорд╛рдирд╛ рдЬрд╛рддрд╛ рд╣реИ, рддреЛ рдЖрдкрдХреЛ рдЗрд╕реЗ рдХрд┐рд╕реА рддрд░рд╣ рд╕реЗ рдЕрд▓рдЧ рддрд░реАрдХреЗ рд╕реЗ рд╕рдВрднрд╛рд▓рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред
рдЗрд╕ рдлрд┐рдХреНрд╕ рдХреЗ рдмрд╛рдж, getLast рд░рдирдЯрд╛рдЗрдо рд▓рдЧрднрдЧ 300 рдПрдордПрд╕ рд╣реЛрдиреЗ рдХреА рдЙрдореНрдореАрдж рд╣реИред рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдпрд╣ рд╕рдордп рдереЛрдбрд╝рд╛ рдмрдврд╝реЗрдЧрд╛, рднрд▓реЗ рд╣реА рдЕрдиреБрд░реЛрдз рдкреИрдХреЗрдЯ рдЖрдХрд╛рд░ рдкрд░ рдкреНрд░рддрд┐рдмрдВрдзреЛрдВ рдореЗрдВ рдлрд┐рдЯ рди рд╣реЛрдВ (рдХреНрдпреЛрдВрдХрд┐ рдкреИрдХреЗрдЯ рд╕рдорд╛рдирд╛рдВрддрд░ рдореЗрдВ рдЕрдиреБрд░реЛрдз рдХрд┐рдП рдЬрд╛рддреЗ рд╣реИрдВ)ред рдЖрдкрдХреЛ рдпрд╛рдж рджрд┐рд▓рд╛рддрд╛ рд╣реВрдВ рдХрд┐ рд╣рдорд╛рд░рд╛ рдиреНрдпреВрдирддрдо рд▓рдХреНрд╖реНрдп 500 рдПрдордПрд╕ рд╣реИ, рдФрд░ 250 рдПрдордПрд╕ рдХреЛ рд╕рд╛рдорд╛рдиреНрдп рдХрд╛рдо рдорд╛рдирд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред
рд╕рдорд╛рдирддрд╛рд▓реЗрдХрд┐рди рдЖрдкрдХреЛ рдЖрдЧреЗ рдмрдврд╝рдиреЗ рдХреА рдЬрд░реВрд░рдд рд╣реИред UserRepository рдФрд░ fileRepository рдХреЗ рдХреЙрд▓ рдкреВрд░реА рддрд░рд╣ рд╕реЗ рд╕реНрд╡рддрдВрддреНрд░ рд╣реИрдВ, рдФрд░ рдЙрдиреНрд╣реЗрдВ рдЖрд╕рд╛рдиреА рд╕реЗ рд╕рдорд╛рдирд╛рдВрддрд░ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рд╕рд┐рджреНрдзрд╛рдВрдд рдореЗрдВ 200 рдПрдордПрд╕ред
рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рд╣рдорд╛рд░реЗ рдЬреЙрдЗрди рдлрдВрдХреНрд╢рди рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ:override fun getLast ( n : Int ) =
messageRepository . findLast ( n )
. let { messages ->
// , forward reply
val allMessages = messages . asSequence () . flatMap { message ->
sequenceOf ( message , message . forwardFrom , message . replyTo )
. filterNotNull ()
} . toSet ()
join ( {
// ,
allMessages . map { it . author } . parallelStream () . distinct ()
. chunked ( userApiChunkLimit , userRepository ::getUsersByIds )
. flatten ()
. associateBy { it . id }
} , {
//
fileRepository . getHeadsByIds ( allMessages . flatMap { it . files ?: listOf () } . toSet ())
. associateBy { it . id }
} ) . let { ( users , files ) ->
messages . map ( recursiveMemoize { message , memoized : ( ChatMessage ) -> ChatMessageUI ->
message . toFrontModel (
getUser = users ::get . orThrow { IllegalArgumentException ( "User $ it" ) } ,
getFile = files ::get . orThrow { IllegalArgumentException ( "File $ it " ) } ,
//
serializeMessage = memoized
)
} )
}
}
рдЬреИрд╕рд╛ рдХрд┐ рдЕрднреНрдпрд╛рд╕ рд╕реЗ рдкрддрд╛ рдЪрд▓рддрд╛ рд╣реИ, рдирд┐рд╖реНрдкрд╛рджрди рдореЗрдВ рд▓рдЧрднрдЧ 200 рдПрдордПрд╕ рд▓рдЧрддреЗ рд╣реИрдВ, рдФрд░ рдпрд╣ рдмрд╣реБрдд рдорд╣рддреНрд╡рдкреВрд░реНрдг рд╣реИ рдХрд┐ рд╕рдВрджреЗрд╢реЛрдВ рдХреА рд╕рдВрдЦреНрдпрд╛ рдореЗрдВ рд╡реГрджреНрдзрд┐ рдХреЗ рд╕рд╛рде рд╕рдордп рдмрд╣реБрдд рдЕрдзрд┐рдХ рдирд╣реАрдВ рдмрдврд╝рддрд╛ рд╣реИред
рд╕рдорд╕реНрдпрд╛рдУрдВрд╕рд╛рдорд╛рдиреНрдп рддреМрд░ рдкрд░, рдХреЛрдб, рдирд┐рд╢реНрдЪрд┐рдд рд░реВрдк рд╕реЗ, рд╣рдорд╛рд░реЗ рднреЛрд▓реЗ рдкрд╣рд▓реЗ рд╕рдВрд╕реНрдХрд░рдг рдХреА рддреБрд▓рдирд╛ рдореЗрдВ рдХрдо рдкрдардиреАрдп рд╣реИ, рд▓реЗрдХрд┐рди рдпрд╣ рдЕрдЪреНрдЫрд╛ рд╣реИ рдХрд┐ рдХреНрд░рдордмрджреНрдзрддрд╛ рд╣реА (toFrontModel рдХреЗ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди) рд▓рдЧрднрдЧ рдирд╣реАрдВ рдмрджрд▓реА рдФрд░ рдкреВрд░реА рддрд░рд╣ рд╕реЗ рдкрдардиреАрдп рдмрдиреА рд░рд╣реАред рдмрд╛рд╣рд░реА рд╕реЗрд╡рд╛рдУрдВ рдХреЗ рд╕рд╛рде рдЪрд╛рд▓рд╛рдХ рдХрд╛рдо рдХрд╛ рдкреВрд░рд╛ рддрд░реНрдХ рдПрдХ рд╣реА рд╕реНрдерд╛рди рдкрд░ рд░рд╣рддрд╛ рд╣реИред
рдЗрд╕ рджреГрд╖реНрдЯрд┐рдХреЛрдг рдХрд╛ рдирдХрд╛рд░рд╛рддреНрдордХ рдкрдХреНрд╖ рдпрд╣ рд╣реИ рдХрд┐ рд╣рдорд╛рд░рд╛ рдЕрдореВрд░реНрдд рдХрд╛рд░реНрдп рдЖрдЧреЗ рдмрдврд╝ рд░рд╣рд╛ рд╣реИред
рдпрджрд┐ рд╣рдореЗрдВ toFrontModel рдореЗрдВ рдкрд░рд┐рд╡рд░реНрддрди рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рддреЛ рд╣рдореЗрдВ рд▓рдЧрднрдЧ рдирд┐рд╢реНрдЪрд┐рдд рд░реВрдк рд╕реЗ getLast рдлрд╝рдВрдХреНрд╢рди рдореЗрдВ рдкрд░рд┐рд╡рд░реНрддрди рдХрд░рдиреЗ рд╣реЛрдВрдЧреЗ, рдЬреЛ рдХрд┐
рдкреНрд░рддрд┐рд╕реНрдерд╛рдкрди рдмрд╛рд░рдмрд░рд╛ рд▓рд┐рд╕реНрдХреЙрд╡ (Liskov рдкреНрд░рддрд┐рд╕реНрдерд╛рдкрди рд╕рд┐рджреНрдзрд╛рдВрдд) рдХреЗ
рд╕рд┐рджреНрдзрд╛рдВрдд рдХрд╛ рдЙрд▓реНрд▓рдВрдШрди рдХрд░рддрд╛ рд╣реИред
рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рд╣рдо рд╕рдВрд▓рдЧреНрди рдлрд╝рд╛рдЗрд▓реЛрдВ рдХреЛ рдХреЗрд╡рд▓ рдореБрдЦреНрдп рд╕рдВрджреЗрд╢реЛрдВ рдореЗрдВ рдбрд┐рдХреНрд░рд┐рдкреНрдЯ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╕рд╣рдордд рд╣реБрдП, рд▓реЗрдХрд┐рди рдЙрддреНрддрд░реЛрдВ рдореЗрдВ рдФрд░ рдЖрдЧреЗ (рдЙрддреНрддрд░ / рдЖрдЧреЗ) рдореЗрдВ рдирд╣реАрдВ, рдпрд╛ рдХреЗрд╡рд▓ рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛рдУрдВ рдореЗрдВ рдФрд░ рдкрд╣рд▓реЗ рд╕реНрддрд░ рдХреЗ рдЖрдЧреЗред рдЗрд╕ рд╕реНрдерд┐рддрд┐ рдореЗрдВ, toFrontModel рдХреЛрдб рдореЗрдВ рдкрд░рд┐рд╡рд░реНрддрди рдХрд░рдиреЗ рдХреЗ рдмрд╛рдж, рдЖрдкрдХреЛ рдлрд╝рд╛рдЗрд▓реЛрдВ рдХреЗ рд▓рд┐рдП рдЕрдиреБрд░реЛрдз рд╕рдВрдЧреНрд░рд╣ рдХреЛрдб рдореЗрдВ рд╕рдВрдмрдВрдзрд┐рдд рд╕реБрдзрд╛рд░ рдХрд░рдирд╛ рд╣реЛрдЧрд╛ред рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рд╕реБрдзрд╛рд░ nontrivial рд╣реЛрдЧрд╛:
fileRepository . getHeadsByIds (
allMessages . flatMap { it . files ?: listOf () } . toSet ()
)
рдФрд░ рдпрд╣рд╛рдВ рд╣рдо рдЖрд╕рд╛рдиреА рд╕реЗ рдПрдХ рдФрд░ рд╕рдорд╕реНрдпрд╛ рд╕реЗ рд╕рдВрдкрд░реНрдХ рдХрд░ рд░рд╣реЗ рд╣реИрдВ рдЬреЛ рдкрд┐рдЫрд▓реЗ рдПрдХ рд╕реЗ рдЬреБрдбрд╝рд╛ рд╣реБрдЖ рд╣реИ: рдПрдХ рдкреВрд░реЗ рдХреЗ рд░реВрдк рдореЗрдВ рдХреЛрдб рдХрд╛ рд╕рд╣реА рд╕рдВрдЪрд╛рд▓рди рд░рд┐рд╡рд░реНрд╕ рдЗрдВрдЬреАрдирд┐рдпрд░рд┐рдВрдЧ рдХреА рд╕рд╛рдХреНрд╖рд░рддрд╛ рдкрд░ рдирд┐рд░реНрднрд░ рдХрд░рддрд╛ рд╣реИред рдХреБрдЫ рдЬрдЯрд┐рд▓ рдорд╛рдорд▓реЛрдВ рдореЗрдВ, рдЧрд▓рдд рдХреНрд╡реЗрд░реА рд╕рдВрдЧреНрд░рд╣ рдХреЗ рдХрд╛рд░рдг рдХреЛрдб рдареАрдХ рд╕реЗ рдХрд╛рдо рдирд╣реАрдВ рдХрд░ рд╕рдХрддрд╛ рд╣реИред рдЗрд╕ рдмрд╛рдд рдХреА рдХреЛрдИ рдЧрд╛рд░рдВрдЯреА рдирд╣реАрдВ рд╣реИ рдХрд┐ рдЖрдк рдпреВрдирд┐рдЯ рдкрд░реАрдХреНрд╖рдгреЛрдВ рдХреЗ рд╕рд╛рде рдЬрд▓реНрджреА рд╕реЗ рдЖрдиреЗ рдореЗрдВ рд╕рдХреНрд╖рдо рд╣реЛрдВрдЧреЗ рдЬреЛ рдЗрд╕ рддрд░рд╣ рдХреА рд╕рднреА рдореБрд╢реНрдХрд┐рд▓ рдкрд░рд┐рд╕реНрдерд┐рддрд┐рдпреЛрдВ рдХреЛ рдХрд╡рд░ рдХрд░реЗрдВрдЧреЗред
рдирд┐рд╖реНрдХрд░реНрд╖рдкреЗрд╢реЗрд╡рд░реЛрдВ:
- рдЕрдиреБрд░реЛрдзреЛрдВ рдХреЛ рдкреВрд░реНрд╡-рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХрд╛ рдПрдХ рд╕реНрдкрд╖реНрдЯ рддрд░реАрдХрд╛, рдЬреЛ рдЖрд╕рд╛рдиреА рд╕реЗ рдореБрдЦреНрдп рдХреЛрдб рд╕реЗ рдЕрд▓рдЧ рд╣реЛ рдЬрд╛рддрд╛ рд╣реИред
- рдореЗрдореЛрд░реА рдФрд░ рдЯрд╛рдЗрдо рдУрд╡рд░рд╣реЗрдб рдХреА рд▓рдЧрднрдЧ рдкреВрд░реНрдг рдЕрдиреБрдкрд╕реНрдерд┐рддрд┐ рдХреЗрд╡рд▓ рдЙрд╕ рдбреЗрдЯрд╛ рдХреЗ рдЙрдкрдпреЛрдЧ рд╕реЗ рдЬреБрдбрд╝реА рд╣реИ рдЬреЛ рд╡реИрд╕реЗ рднреА рдкреНрд░рд╛рдкреНрдд рд╣реБрдИ рд╣реЛрдЧреАред
- рдЕрдЪреНрдЫрд╛ рд╕реНрдХреЗрд▓рд┐рдВрдЧ рдФрд░ рдПрдХ рд╕реЗрд╡рд╛ рдХрд╛ рдирд┐рд░реНрдорд╛рдг рдХрд░рдиреЗ рдХреА рдХреНрд╖рдорддрд╛, рдЬреЛ рд╕рд┐рджреНрдзрд╛рдВрдд рд░реВрдк рдореЗрдВ рдмрд╛рд╣рд░ рд╕реЗ рдЕрдиреБрд░реЛрдз рдХреЗ рдЖрдХрд╛рд░ рдХреА рдкрд░рд╡рд╛рд╣ рдХрд┐рдП рдмрд┐рдирд╛, рдПрдХ рдЕрдиреБрдорд╛рдирд┐рдд рд╕рдордп рдХреЗ рд▓рд┐рдП рдЬрд┐рдореНрдореЗрджрд╛рд░ рд╣реЛрдЧреАред
рд╡рд┐рдкрдХреНрд╖:
- рдмреИрдЪ рдкреНрд░реЛрд╕реЗрд╕рд┐рдВрдЧ рдХреЗ рд▓рд┐рдП рдмрд╣реБрдд рд╣реА рдЬрдЯрд┐рд▓ рдХреЛрдбред
- рдореМрдЬреВрджрд╛ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдореЗрдВ рдЕрдиреБрд░реЛрдзреЛрдВ рдХреЗ рд╡рд┐рд╢реНрд▓реЗрд╖рдг рдкрд░ рдмрдбрд╝рд╛ рдФрд░ рдЬрд┐рдореНрдореЗрджрд╛рд░ рдХрд╛рдоред
- рдмрд╣рддреА рдЕрдореВрд░реНрддрддрд╛ рдФрд░, рдкрд░рд┐рдгрд╛рдорд╕реНрд╡рд░реВрдк, рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдореЗрдВ рдкрд░рд┐рд╡рд░реНрддрди рдХреЗ рд╕рдВрдмрдВрдз рдореЗрдВ рдкреВрд░реА рдпреЛрдЬрдирд╛ рдХреА рдирд╛рдЬреБрдХрддрд╛ред
- рд╕рдорд░реНрдерди рдореЗрдВ рдХрдард┐рдирд╛рдЗрдпрд╛рдБ: рдХреНрд╡реЗрд░реА рднрд╡рд┐рд╖реНрдпрд╡рд╛рдгреА рдмреНрд▓реЙрдХ рдореЗрдВ рддреНрд░реБрдЯрд┐рдпреЛрдВ рдХреЛ рдореБрдЦреНрдп рдХреЛрдб рдореЗрдВ рддреНрд░реБрдЯрд┐рдпреЛрдВ рд╕реЗ рдЕрд▓рдЧ рдХрд░рдирд╛ рдореБрд╢реНрдХрд┐рд▓ рд╣реИред рдЖрджрд░реНрд╢ рд░реВрдк рд╕реЗ, рдЖрдкрдХреЛ рджреЛ рдмрд╛рд░ рдХрдИ рдпреВрдирд┐рдЯ рдкрд░реАрдХреНрд╖рдгреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рдЗрд╕рд▓рд┐рдП рдЙрддреНрдкрд╛рджрди рдореЗрдВ рддреНрд░реБрдЯрд┐рдпреЛрдВ рдХреЗ рд╕рд╛рде рдХрд╛рд░реНрдпрд╡рд╛рд╣реА рджреЛ рдмрд╛рд░ рдореБрд╢реНрдХрд┐рд▓ рд╣реЛрдЧреАред
- рдХреЛрдб рд▓рд┐рдЦрддреЗ рд╕рдордп SOLID рд╕рд┐рджреНрдзрд╛рдВрддреЛрдВ рдХрд╛ рдЕрдиреБрдкрд╛рд▓рди: рдмреИрдЪ рдкреНрд░рд╕рдВрд╕реНрдХрд░рдг рдХреЗ рддрд░реНрдХ рдХреЛ рдЕрд▓рдЧ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХреЛрдб рддреИрдпрд╛рд░ рдХрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдПред рдЕрдХреЗрд▓реЗ рдЗрди рд╕рд┐рджреНрдзрд╛рдВрддреЛрдВ рдХрд╛ рдкрд░рд┐рдЪрдп рдХреБрдЫ рд▓рд╛рдн рдкреНрд░рджрд╛рди рдХрд░реЗрдЧрд╛, рдЗрд╕рд▓рд┐рдП рдпрд╣ рдЛрдг рд╕рдмрд╕реЗ рдорд╣рддреНрд╡рд╣реАрди рд╣реИред
рдпрд╣ рдзреНрдпрд╛рди рд░рдЦрдирд╛ рдорд╣рддреНрд╡рдкреВрд░реНрдг рд╣реИ рдХрд┐ рдЖрдк рдЗрд╕ рд╡рд┐рдзрд┐ рдХрд╛ рдЙрдкрдпреЛрдЧ рд░рд┐рд╡рд░реНрд╕ рдЗрдВрдЬреАрдирд┐рдпрд░рд┐рдВрдЧ рдХрд┐рдП рдмрд┐рдирд╛ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рд╣рдореЗрдВ рдПрдХ рдЧреЗрдЯрд▓рд╛рд╕реНрдЯ рдЕрдиреБрдмрдВрдз рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рдЬрд┐рд╕ рдкрд░ рдЕрдиреБрд░реЛрдзреЛрдВ рдХреА рдкреНрд░рд╛рд░рдВрднрд┐рдХ рдЧрдгрдирд╛ рдХреЗ рд▓рд┐рдП рдЕрдиреБрдмрдВрдз рдирд┐рд░реНрднрд░ рдХрд░рддрд╛ рд╣реИ (рдмрд╛рдж рдореЗрдВ - рдкреНрд░реАрдлреИрдЪ)ред рдЗрд╕ рдорд╛рдорд▓реЗ рдореЗрдВ, рд╣рдордиреЗ рдЧреЗрдЯрд▓рд╛рд╕реНрдЯ (рд░рд┐рд╡рд░реНрд╕ рдЗрдВрдЬреАрдирд┐рдпрд░рд┐рдВрдЧ) рдХреЗ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреЛ рджреЗрдЦрддреЗ рд╣реБрдП рдРрд╕рд╛ рдХрд┐рдпрд╛ред рд╣рд╛рд▓рд╛рдВрдХрд┐, рдЗрд╕ рджреГрд╖реНрдЯрд┐рдХреЛрдг рдХреЗ рд╕рд╛рде, рдХрдард┐рдирд╛рдЗрдпрд╛рдВ рдЙрддреНрдкрдиреНрди рд╣реЛрддреА рд╣реИрдВ: рдХреЛрдб рдХреЗ рдЗрди рджреЛ рдЯреБрдХрдбрд╝реЛрдВ рдХреЛ рд╕рдВрдкрд╛рджрд┐рдд рдХрд░рдирд╛ рд╣рдореЗрд╢рд╛ рд╕рдордХрд╛рд▓рд┐рдХ рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдП, рдФрд░ рдпрд╣ рд╕реБрдирд┐рд╢реНрдЪрд┐рдд рдХрд░рдирд╛ рдЕрд╕рдВрднрд╡ рд╣реИ (рд╣реИрд╢рдХреЛрдб рдФрд░ рдмрд░рд╛рдмрд░ рдпрд╛рдж рд░рдЦреЗрдВ, рдмрд┐рд▓реНрдХреБрд▓ рд╡рд╣реА рдмрд╛рдд рд╣реИ)ред рдЕрдЧрд▓рд╛ рджреГрд╖реНрдЯрд┐рдХреЛрдг, рдЬрд┐рд╕реЗ рдореИрдВ рджрд┐рдЦрд╛рдирд╛ рдЪрд╛рд╣реВрдВрдЧрд╛, рдЗрд╕ рд╕рдорд╕реНрдпрд╛ рдХреЛ рд╣рд▓ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдбрд┐рдЬрд╝рд╛рдЗрди рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ (рдпрд╛ рдХрдо рд╕реЗ рдХрдо рд╢рдорди)ред
рд╡реНрдпрд╛рдкрд╛рд░ рдХреЗ рдЖрдВрдХрдбрд╝реЗ
рдПрдХ рдЕрдиреБрдмрдВрдз рдХрд╛ рд╕рдорд╛рдзрд╛рдирдХреНрдпрд╛ рд╣реЛрдЧрд╛ рдЕрдЧрд░ рд╣рдо рдПрдХ рд╕рдЯреАрдХ рдЕрдиреБрдмрдВрдз рдХреЗ рд╕рд╛рде рдХрд╛рдо рдирд╣реАрдВ рдХрд░рддреЗ рд╣реИрдВ рдФрд░ рдЗрд╕рд▓рд┐рдП, рдЕрдиреБрд░реЛрдзреЛрдВ рдХреЗ рд╕рдЯреАрдХ рд╕реЗрдЯ рдХреЗ рд╕рд╛рде, рд▓реЗрдХрд┐рди рд▓рдЧрднрдЧ рдПрдХ рдХреЗ рд╕рд╛рде? рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рд╣рдо рдПрдХ рдЕрдиреБрдорд╛рдирд┐рдд рд╕реЗрдЯ рдмрдирд╛рдПрдВрдЧреЗ рддрд╛рдХрд┐ рдЗрд╕рдореЗрдВ рд╕рдЯреАрдХ рд╕реЗрдЯ рд╢рд╛рдорд┐рд▓ рд╣реЛ рдФрд░ рдпрд╣ рд╡рд┐рд╖рдп рдХреНрд╖реЗрддреНрд░ рдХреА рд╡рд┐рд╢реЗрд╖рддрд╛рдУрдВ рдкрд░ рдЖрдзрд╛рд░рд┐рдд рд╣реЛред
рдЗрд╕ рдкреНрд░рдХрд╛рд░, рдЧреЗрдЯрд▓реЗрд╕реНрдЯ рдкрд░ рдкреНрд░реАрдлреИрдЪ рдЕрдиреБрдмрдВрдз рдХреА рдирд┐рд░реНрднрд░рддрд╛ рдХреЗ рдмрдЬрд╛рдп, рд╣рдо рдЙрди рджреЛрдиреЛрдВ рдХреА рдирд┐рд░реНрднрд░рддрд╛ рдХреЛ рдХреБрдЫ рд╕рд╛рдорд╛рдиреНрдп рдЕрдиреБрдмрдВрдз рдкрд░ рд╕реНрдерд╛рдкрд┐рдд рдХрд░рддреЗ рд╣реИрдВ рдЬреЛ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рджреНрд╡рд╛рд░рд╛ рддрдп рдХрд┐рдП рдЬрд╛рдПрдВрдЧреЗред рдореБрдЦреНрдп рдХрдард┐рдирд╛рдИ рдХреЛрдб рдХреЗ рд░реВрдк рдореЗрдВ рдХрд┐рд╕реА рднреА рддрд░рд╣ рдЗрд╕ рд╕рд╛рдорд╛рдиреНрдп рдЕрдиреБрдмрдВрдз рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдирд╛ рд╣реЛрдЧрд╛ред
рдЙрдкрдпреЛрдЧреА рд╕реАрдорд╛рдУрдВ рдХреА рдЦреЛрдЬ рдХрд░реЗрдВрдЖрдЗрдП рд╣рдорд╛рд░реЗ рдЙрджрд╛рд╣рд░рдг рдХреЗ рд╕рд╛рде рдРрд╕рд╛ рдХрд░рдиреЗ рдХрд╛ рдкреНрд░рдпрд╛рд╕ рдХрд░реЗрдВред
рд╣рдорд╛рд░реЗ рдорд╛рдорд▓реЗ рдореЗрдВ, рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рд╡реНрдпрд╡рд╕рд╛рдп рд╡рд┐рд╢реЗрд╖рддрд╛рдПрдВ рд╣реИрдВ:
- рдЪреИрдЯ рдкреНрд░рддрд┐рднрд╛рдЧрд┐рдпреЛрдВ рдХреА рд╕реВрдЪреА рдкреВрд░реНрд╡рдирд┐рд░реНрдзрд╛рд░рд┐рдд рд╣реИ;
- рдЪреИрдЯ рдПрдХ рджреВрд╕рд░реЗ рд╕реЗ рдкреВрд░реА рддрд░рд╣ рд╕реЗ рдЕрд▓рдЧ рд╣реИрдВ;
- рдЙрддреНрддрд░ / рдЖрдЧреЗ рдХреА рдЬрдВрдЬреАрд░реЛрдВ рдХрд╛ рдШреЛрдВрд╕рд▓рд╛ рдЫреЛрдЯрд╛ рд╣реЛрддрд╛ рд╣реИ (~ 2тАУ3 рд╕рдВрджреЗрд╢)ред
рдкрд╣рд▓реЗ рдкреНрд░рддрд┐рдмрдВрдз рд╕реЗ рдпрд╣ рдЗрд╕ рдкреНрд░рдХрд╛рд░ рд╣реИ рдХрд┐ рдЖрдкрдХреЛ рд╕рдВрджреЗрд╢реЛрдВ рдХреЛ рдЪрд▓рд╛рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИ, рдпрд╣ рджреЗрдЦреЗрдВ рдХрд┐ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХреНрдпрд╛ рд╣реИрдВ, рдЕрдирдиреНрдп рд▓реЛрдЧреЛрдВ рдХреЛ рдЪреБрдиреЗрдВ рдФрд░ рдЙрдирдХреЗ рд▓рд┐рдП рдЕрдиреБрд░реЛрдз рдХрд░реЗрдВред рдЖрдк рдмрд╕ рдПрдХ рдкреВрд░реНрд╡рдирд┐рд░реНрдзрд╛рд░рд┐рдд рд╕реВрдЪреА рдХреЛ рдХреНрд╡реЗрд░реА рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рдпрджрд┐ рдЖрдк рдЗрд╕ рдХрдерди рд╕реЗ рд╕рд╣рдордд рд╣реИрдВ, рддреЛ рдореИрдВрдиреЗ рдЖрдкрдХреЛ рдкрдХрдбрд╝ рд▓рд┐рдпрд╛ред
рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ, рд╕рдм рдХреБрдЫ рдЗрддрдирд╛ рд╕рд░рд▓ рдирд╣реАрдВ рд╣реИред рдПрдХ рд╕реВрдЪреА рдХреЛ рдкреВрд░реНрд╡рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рд╣рдЬрд╛рд░реЛрдВ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рд╣реЛ рд╕рдХрддреЗ рд╣реИрдВред рдРрд╕реА рдмрд╛рддреЛрдВ рдХреЛ рд╕реНрдкрд╖реНрдЯ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред рд╣рдорд╛рд░реЗ рдорд╛рдорд▓реЗ рдореЗрдВ, рдЖрдорддреМрд░ рдкрд░ рджреЛ рдпрд╛ рддреАрди рдЪреИрдЯ рдкреНрд░рддрд┐рднрд╛рдЧреА рд╣реЛрдВрдЧреЗ, рд╢рд╛рдпрдж рд╣реА рдХрднреА рдЕрдзрд┐рдХред рддреЛ рдпрд╣ рдЙрди рд╕рднреА рдкрд░ рдбреЗрдЯрд╛ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдкреВрд░реА рддрд░рд╣ рд╕реЗ рд╕реНрд╡реАрдХрд╛рд░реНрдп рд╣реИред
рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдЕрдЧрд░ рдЪреИрдЯ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛рдУрдВ рдХреА рд╕реВрдЪреА рдкреВрд░реНрд╡ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рд╣реИ, рд▓реЗрдХрд┐рди рдпрд╣ рдЬрд╛рдирдХрд╛рд░реА рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рд╕реЗрд╡рд╛ рдореЗрдВ рдирд╣реАрдВ рд╣реИ (рдЬреЛ рдмрд╣реБрдд рд╕рдВрднрд╛рд╡рдирд╛ рд╣реИ), рддреЛ рдРрд╕реА рдЬрд╛рдирдХрд╛рд░реА рд╕реЗ рдХреЛрдИ рдорддрд▓рдм рдирд╣реАрдВ рд╣реЛрдЧрд╛ред рд╣рдо рдЪреИрдЯ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рд╕реВрдЪреА рдХреЗ рд▓рд┐рдП рдПрдХ рдЕрддрд┐рд░рд┐рдХреНрдд рдЕрдиреБрд░реЛрдз рдХрд░реЗрдВрдЧреЗ, рдФрд░ рдлрд┐рд░ рдЖрдкрдХреЛ рдЕрднреА рднреА рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рд╕реЗрд╡рд╛ рдХреЗ рд▓рд┐рдП рдЕрдиреБрд░реЛрдз рдХрд░рдирд╛ рд╣реЛрдЧрд╛ред
рдорд╛рди рд▓реАрдЬрд┐рдП рдХрд┐ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛рдУрдВ рдФрд░ рдХрдиреЗрдХреНрд╢рди рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЬрд╛рдирдХрд╛рд░реА рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рд╕реЗрд╡рд╛ рдореЗрдВ рд╕рдВрдЧреНрд░рд╣реАрдд рд╣реИред рд╣рдорд╛рд░реЗ рдорд╛рдорд▓реЗ рдореЗрдВ, рдпрд╣ рдРрд╕рд╛ рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рдХрдиреЗрдХреНрд╢рди рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХреЗ рдЕрдзрд┐рдХрд╛рд░реЛрдВ рджреНрд╡рд╛рд░рд╛ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рддрдм рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛рдУрдВ рдХреЗ рд▓рд┐рдП рдпрд╣ рдЗрд╕ рддрд░рд╣ рдХреЗ рдПрдХ рдкреНрд░реАрдлреИрдЪ рдХреЛрдб рдХреЛ рдмрдВрдж рдХрд░ рджреЗрдЧрд╛:
рдпрд╣рд╛рдБ рдпрд╣ рдЖрд╢реНрдЪрд░реНрдпрдЬрдирдХ рд▓рдЧ рд╕рдХрддрд╛ рд╣реИ рдХрд┐ рд╣рдо рдХрд┐рд╕реА рднреА рдЪреИрдЯ рдЖрдЗрдбреЗрдВрдЯрд┐рдлрд╝рд╛рдпрд░ рдХреЛ рдкрд╛рд╕ рдирд╣реАрдВ рдХрд░ рд░рд╣реЗ рд╣реИрдВред рдореИрдВрдиреЗ рдЬрд╛рдирдмреВрдЭрдХрд░ рдРрд╕рд╛ рдХрд┐рдпрд╛ рдерд╛ рддрд╛рдХрд┐ рдирдореВрдирд╛ рдХреЛрдб рдХреЛ рдЕрд╡реНрдпрд╡рд╕реНрдерд┐рдд рди рдХрд░реВрдВред
рдкрд╣рд▓реА рдирдЬрд╝рд░ рдореЗрдВ, рджреВрд╕рд░реЗ рдкреНрд░рддрд┐рдмрдВрдз рд╕реЗ рдХреБрдЫ рднреА рдирд╣реАрдВ рд╣реЛрддрд╛ рд╣реИред рдХрд┐рд╕реА рднреА рд╕реНрдерд┐рддрд┐ рдореЗрдВ, рдореБрдЭреЗ рдЕрднреА рднреА рдЙрд╕рд╕реЗ рдЙрдкрдпреЛрдЧреА рдХреБрдЫ рднреА рдирд╣реАрдВ рдорд┐рд▓рд╛ред
рд╣рдордиреЗ рдкрд╣рд▓реЗ рд╣реА рддреАрд╕рд░реЗ рдкреНрд░рддрд┐рдмрдВрдз рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рд╣реИред рдпрд╣ рдЗрд╕ рдмрд╛рдд рдкрд░ рдорд╣рддреНрд╡рдкреВрд░реНрдг рдкреНрд░рднрд╛рд╡ рдбрд╛рд▓ рд╕рдХрддрд╛ рд╣реИ рдХрд┐ рд╣рдо рдмрд╛рддрдЪреАрдд рдХреИрд╕реЗ рд╕рдВрдЧреНрд░рд╣реАрдд рдХрд░рддреЗ рд╣реИрдВ рдФрд░ рдкреНрд░рд╛рдкреНрдд рдХрд░рддреЗ рд╣реИрдВред рд╣рдо рдЗрд╕ рд╡рд┐рд╖рдп рдХреЛ рд╡рд┐рдХрд╕рд┐рдд рдХрд░рдирд╛ рд╢реБрд░реВ рдирд╣реАрдВ рдХрд░реЗрдВрдЧреЗ, рдХреНрдпреЛрдВрдХрд┐ рдЗрд╕рдХрд╛ рдЖрд░рдИрдПрд╕рдЯреА рдирд┐рдпрдВрддреНрд░рдХ рдФрд░ рдмреИрдЪ рдкреНрд░рд╕рдВрд╕реНрдХрд░рдг рд╕реЗ рдХреЛрдИ рд▓реЗрдирд╛-рджреЗрдирд╛ рдирд╣реАрдВ рд╣реИред
рдлрд╝рд╛рдЗрд▓реЛрдВ рдХреЗ рд╕рд╛рде рдХреНрдпрд╛ рдХрд░рдирд╛ рд╣реИ? рдореИрдВ рдПрдХ рд╕рд░рд▓ рдЕрдиреБрд░реЛрдз рдореЗрдВ рд╕рднреА рдЪреИрдЯ рдлрд╝рд╛рдЗрд▓реЛрдВ рдХреА рдПрдХ рд╕реВрдЪреА рдкреНрд░рд╛рдкреНрдд рдХрд░рдирд╛ рдЪрд╛рд╣рддрд╛ рд╣реВрдВред рдПрдкреАрдЖрдИ рдХреА рд╢рд░реНрддреЛрдВ рдХреЗ рддрд╣рдд, рд╣рдореЗрдВ рдХреЗрд╡рд▓ рдирд┐рдХрд╛рдп рдХреЗ рдмрд┐рдирд╛, рдлрд╝рд╛рдЗрд▓ рд╣реЗрдбрд░ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИ, рдЗрд╕рд▓рд┐рдП рдпрд╣ рдХреЙрд▓рд░ рдХреЗ рд▓рд┐рдП рд╕рдВрд╕рд╛рдзрди-рдЧрд╣рди рдФрд░ рдЦрддрд░рдирд╛рдХ рдХрд╛рд░реНрдп рдХреА рддрд░рд╣ рдирд╣реАрдВ рджрд┐рдЦрддрд╛ рд╣реИред
рджреВрд╕рд░реА рдУрд░, рд╣рдореЗрдВ рдпрд╣ рдпрд╛рдж рд░рдЦрдирд╛ рдЪрд╛рд╣рд┐рдП рдХрд┐ рд╣рдореЗрдВ рд╕рднреА рдЪреИрдЯ рд╕рдВрджреЗрд╢ рдирд╣реАрдВ рдорд┐рд▓рддреЗ рд╣реИрдВ, рд▓реЗрдХрд┐рди рдХреЗрд╡рд▓ рдЕрдВрддрд┐рдо рдПрди, рдФрд░ рдпрд╣ рдЖрд╕рд╛рдиреА рд╕реЗ рдкрддрд╛ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдХрд┐ рдЙрдирдореЗрдВ рдХреЛрдИ рднреА рдлрд╛рдЗрд▓ рдирд╣реАрдВ рд╣реИред
рдХреЛрдИ рд╕рд╛рд░реНрд╡рднреМрдорд┐рдХ рдЙрддреНрддрд░ рдирд╣реАрдВ рд╣реЛ рд╕рдХрддрд╛ рд╣реИ: рдпрд╣ рд╕рдм рд╡реНрдпрд╛рдкрд╛рд░ рдХреА рдмрд╛рд░реАрдХрд┐рдпреЛрдВ рдФрд░ рдЙрдкрдпреЛрдЧ рдХреЗ рдорд╛рдорд▓реЛрдВ рдкрд░ рдирд┐рд░реНрднрд░ рдХрд░рддрд╛ рд╣реИред рдЙрддреНрдкрд╛рдж рд╕рдорд╛рдзрд╛рди рдмрдирд╛рддреЗ рд╕рдордп, рдпрджрд┐ рдЖрдк рдПрдХ рдЙрдкрдпреЛрдЧ рдХреЗ рдорд╛рдорд▓реЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдЕрдиреБрдорд╛рди рд▓рдЧрд╛рддреЗ рд╣реИрдВ, рддреЛ рдЖрдк рдореБрд╕реАрдмрдд рдореЗрдВ рдкрдбрд╝ рд╕рдХрддреЗ рд╣реИрдВ, рдФрд░ рдлрд┐рд░ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдПрдХ рдЕрд▓рдЧ рддрд░реАрдХреЗ рд╕реЗ рдХрд╛рд░реНрдпрдХреНрд╖рдорддрд╛ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░реЗрдВрдЧреЗред рдбреЗрдореЛ рдФрд░ рдкреНрд░реАрд╕реЗрд▓реНрд╕ рдХреЗ рд▓рд┐рдП, рдпрд╣ рдПрдХ рдЕрдЪреНрдЫрд╛ рд╡рд┐рдХрд▓реНрдк рд╣реИ, рд▓реЗрдХрд┐рди рдЕрднреА рд╣рдо рдПрдХ рдИрдорд╛рдирджрд╛рд░ рдЙрддреНрдкрд╛рджрди рд╕реЗрд╡рд╛ рд▓рд┐рдЦрдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░ рд░рд╣реЗ рд╣реИрдВред
рддреЛ, рдЕрдлрд╕реЛрд╕, рдпрд╣ рдХреЗрд╡рд▓ рд╕рдВрдЪрд╛рд▓рди рдФрд░ рд╕рд╛рдВрдЦреНрдпрд┐рдХреА рд╕рдВрдЧреНрд░рд╣ (рдпрд╛ рдПрдХ рд╡рд┐рд╢реЗрд╖рдЬреНрдЮ рдореВрд▓реНрдпрд╛рдВрдХрди рдХреЗ рдмрд╛рдж) рдХреЗ рдкрд░рд┐рдгрд╛рдореЛрдВ рдХреЗ рдЖрдзрд╛рд░ рдкрд░ рдпрд╣рд╛рдВ рдлрд╛рдЗрд▓реЛрдВ рдХреЗ рд▓рд┐рдП рд╡реНрдпрд╛рдкрд╛рд░рд┐рдХ рдЙрддреНрддрд░рд╛рдзрд┐рдХрд╛рд░ рдХрд░рдирд╛ рд╕рдВрднрд╡ рд╣реЛрдЧрд╛ред
рдЪреВрдБрдХрд┐ рд╣рдо рдЕрднреА рднреА рдХрд┐рд╕реА рди рдХрд┐рд╕реА рддрд░рд╣ рд╕реЗ рдЕрдкрдиреА рдкрджреНрдзрддрд┐ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ, рддреЛ рдорд╛рди рд▓реАрдЬрд┐рдП рдХрд┐ рдЖрдБрдХрдбрд╝реЗ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рджрд░реНрд╢рд╛рддреЗ рд╣реИрдВ:
- рдПрдХ рдареЗрда рдмрд╛рддрдЪреАрдд рдПрдХ рд╕рдВрджреЗрд╢ рдХреЗ рд╕рд╛рде рд╢реБрд░реВ рд╣реЛрддреА рд╣реИ рдЬрд┐рд╕рдореЗрдВ рдПрдХ рдпрд╛ рдПрдХ рд╕реЗ рдЕрдзрд┐рдХ рдлрд╛рдЗрд▓реЗрдВ рд╢рд╛рдорд┐рд▓ рд╣реЛрддреА рд╣реИрдВ, рдЗрд╕рдХреЗ рдмрд╛рдж рдлрд╝рд╛рдЗрд▓реЛрдВ рдХреЗ рдмрд┐рдирд╛ рдЙрддреНрддрд░ рд╕рдВрджреЗрд╢ рд╢рд╛рдорд┐рд▓ рд╣реЛрддреЗ рд╣реИрдВред
- рд▓рдЧрднрдЧ рд╕рднреА рд╕рдВрджреЗрд╢ рд╡рд┐рд╢рд┐рд╖реНрдЯ рдмрд╛рддрдЪреАрдд рдореЗрдВ рдЖрддреЗ рд╣реИрдВред
- рдПрдХрд▓ рдЪреИрдЯ рдХреЗ рднреАрддрд░ рдЕрджреНрд╡рд┐рддреАрдп рдлрд╝рд╛рдЗрд▓реЛрдВ рдХреА рдЕрдкреЗрдХреНрд╖рд┐рдд рд╕рдВрдЦреНрдпрд╛ ~ 20 рд╣реИред
рдпрд╣ рдЗрд╕ рдкреНрд░рдХрд╛рд░ рд╣реИ рдХрд┐ рд▓рдЧрднрдЧ рд╕рднреА рд╕рдВрджреЗрд╢реЛрдВ рдХреЛ рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЖрдкрдХреЛ рдХреБрдЫ рдлрд╝рд╛рдЗрд▓реЛрдВ рдХреЗ рд╣реЗрдбрд░ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрдЧреА (рдХреНрдпреЛрдВрдХрд┐ ChatMessageUI рдЗрддрдиреА рд╡реНрдпрд╡рд╕реНрдерд╛ рдХреА рдЧрдИ рд╣реИ) рдФрд░ рдХреБрд▓ рдлрд╝рд╛рдЗрд▓реЛрдВ рдХреА рд╕рдВрдЦреНрдпрд╛ рдХрдо рд╣реИред рдЗрд╕ рдорд╛рдорд▓реЗ рдореЗрдВ, рд╕рднреА рдЪреИрдЯ рдлрд╝рд╛рдЗрд▓реЛрдВ рдХреЛ рдПрдХ рдЕрдиреБрд░реЛрдз рдореЗрдВ рдкреНрд░рд╛рдкреНрдд рдХрд░рдирд╛ рдЙрдЪрд┐рдд рд▓рдЧрддрд╛ рд╣реИред рдРрд╕рд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдореЗрдВ рдЕрдкрдиреА API рдХреЛ рдлрд╝рд╛рдЗрд▓реЛрдВ рдХреЗ рд▓рд┐рдП рдЬреЛрдбрд╝рдирд╛ рд╣реЛрдЧрд╛:
fun getHeadsByChat () : List < FileHeadRemote >
GetHeadsByChat рд╡рд┐рдзрд┐ рдкреНрд░рджрд░реНрд╢рди рдХреЛ рдЕрдиреБрдХреВрд▓рд┐рдд рдХрд░рдиреЗ рдХреА рд╣рдорд╛рд░реА рдЗрдЪреНрдЫрд╛ рдХреЗ рдХрд╛рд░рдг рджреВрд░-рджреВрд░ рддрдХ рдирд╣реАрдВ рджрд┐рдЦрддреА рд╣реИ рдФрд░ рд╢реБрджреНрдз рд░реВрдк рд╕реЗ рдмрдирд╛рдИ рдЧрдИ рд╣реИ (рд╣рд╛рд▓рд╛рдВрдХрд┐ рдпрд╣ рднреА рдПрдХ рдЕрдЪреНрдЫрд╛ рдХрд╛рд░рдг рд╣реИ)ред рдмрд╣реБрдд рдмрд╛рд░, рдлрд╝рд╛рдЗрд▓реЛрдВ рдХреЗ рд╕рд╛рде рдЪреИрдЯ рд░реВрдо рдореЗрдВ, рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдЙрдкрдпреЛрдЧ рдХреА рдЧрдИ рд╕рднреА рдлрд╝рд╛рдЗрд▓реЛрдВ рдХреЛ рджреЗрдЦрдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ, рдФрд░ рдХреНрд░рдо рдореЗрдВ рдЙрдиреНрд╣реЗрдВ рдЬреЛрдбрд╝рд╛ рдЧрдпрд╛ рдерд╛ (рдЗрд╕рд▓рд┐рдП, рд╣рдо рд╕реВрдЪреА рдореЗрдВ рд╢рд╛рдорд┐рд▓ рд╣реИрдВ)ред
рдЗрд╕ рддрд░рд╣ рдХреЗ рдПрдХ рд╕реНрдкрд╖реНрдЯ рдХрдиреЗрдХреНрд╢рди рдХреЗ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреЗ рд▓рд┐рдП рдПрдХ рдлрд╝рд╛рдЗрд▓ рд╕реЗрд╡рд╛ рдпрд╛ рд╣рдорд╛рд░реЗ рдЖрд╡реЗрджрди рдореЗрдВ рдЕрддрд┐рд░рд┐рдХреНрдд рдЬрд╛рдирдХрд╛рд░реА рдХреЗ рднрдВрдбрд╛рд░рдг рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрдЧреАред рдпрд╣ рд╕рдм рдЗрд╕ рдмрд╛рдд рдкрд░ рдирд┐рд░реНрднрд░ рдХрд░рддрд╛ рд╣реИ рдХрд┐ рдЬрд╝рд┐рдореНрдореЗрджрд╛рд░реА рдХреЗ рдХреНрд╖реЗрддреНрд░ рдореЗрдВ, рд╣рдорд╛рд░реА рд░рд╛рдп рдореЗрдВ, рдлрд╝рд╛рдЗрд▓ рдХреЗ рдХрдиреЗрдХреНрд╢рди рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдпрд╣ рдЕрдирд╛рд╡рд╢реНрдпрдХ рдЬрд╛рдирдХрд╛рд░реА рд╕рдВрдЧреНрд░рд╣реАрдд рдХреА рдЬрд╛рдиреА рдЪрд╛рд╣рд┐рдПред рдпрд╣ рдирд┐рд░рд░реНрдердХ рд╣реИ рдХреНрдпреЛрдВрдХрд┐ рд╕рдВрджреЗрд╢ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдлрд╝рд╛рдЗрд▓ рдХреЗ рд╕рд╛рде рдЬреБрдбрд╝рд╛ рд╣реБрдЖ рд╣реИ, рдФрд░ рдпрд╣, рдмрджрд▓реЗ рдореЗрдВ, рдЪреИрдЯ рдХреЗ рд╕рд╛рде рдЬреБрдбрд╝рд╛ рд╣реБрдЖ рд╣реИред рдЖрдк рд╡рдиреАрдХрд░рдг рдХрд╛ рдЙрдкрдпреЛрдЧ рдирд╣реАрдВ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рд▓реЗрдХрд┐рди рд╕рдВрджреЗрд╢ рд╕реЗ рдордХреНрдЦреА рдкрд░ рдЗрд╕ рдЬрд╛рдирдХрд╛рд░реА рдХреЛ рдирд┐рдХрд╛рд▓реЗрдВ, рдЕрд░реНрдерд╛рддреН, рдПрд╕рдХреНрдпреВрдПрд▓ рдХреЗ рдЕрдВрджрд░, рддреБрд░рдВрдд рдкреВрд░реА рдЪреИрдЯ рдореЗрдВ рд╕рднреА рдлрд╛рдЗрд▓реЗрдВ рдкреНрд░рд╛рдкреНрдд рдХрд░реЗрдВ (рдпрд╣ рд╣рдорд╛рд░реЗ рдЖрд╡реЗрджрди рдореЗрдВ рд╣реИ) рдФрд░ рдЙрди рд╕рднреА рд╕реЗ рдлрд╝рд╛рдЗрд▓ рд╕реЗрд╡рд╛ рд╕реЗ рдПрдХ рдмрд╛рд░ рдЕрдиреБрд░реЛрдз рдХрд░реЗрдВред рдпрджрд┐ рдмрд╣реБрдд рд╕рд╛рд░реЗ рдЪреИрдЯ рд╕рдВрджреЗрд╢ рд╣реИрдВ, рддреЛ рдпрд╣ рд╡рд┐рдХрд▓реНрдк рдФрд░ рднреА рдмреБрд░рд╛ рдХрд╛рдо рдХрд░реЗрдЧрд╛, рд▓реЗрдХрд┐рди рд╣рдореЗрдВ рдЗрд╕рдХреЗ рдирд╛рдордХрд░рдг рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИред рдореИрдВ getHeadsByChat рдХреЗ рдкреАрдЫреЗ рджреЛрдиреЛрдВ рд╡рд┐рдХрд▓реНрдк рдЫрд┐рдкрд╛рдКрдВрдЧрд╛ред
рдХреЛрдб рдирд┐рдореНрдирд╛рдиреБрд╕рд╛рд░ рд╣реИ:
override fun getLast ( n : Int ) =
messageRepository . findLast ( n )
. let { messages ->
join (
{ userRepository . getUsersByChat () . associateBy { it . id } } ,
{ fileRepository . getHeadsByChat () . associateBy { it . id } }
)
. let { //
}
}
рдпрд╣ рджреЗрдЦрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ рдХрд┐ рдкрд┐рдЫрд▓реЗ рд╕рдВрд╕реНрдХрд░рдг рдХреА рддреБрд▓рдирд╛ рдореЗрдВ, рдмрд╣реБрдд рдХрдо рдмрджрд▓ рдЧрдпрд╛ рд╣реИ рдФрд░ рдХреЗрд╡рд▓ рдкреНрд░реАрдлреИрдЪ рднрд╛рдЧ рдкреНрд░рднрд╛рд╡рд┐рдд рд╣реБрдЖ рд╣реИ, рдЬреЛ рдмрд╣реБрдд рдЕрдЪреНрдЫрд╛ рд╣реИред
рдкреНрд░реАрдлрд╝реИрдЪ рдХреЛрдб рдмрд╣реБрдд рдЫреЛрдЯрд╛ рдФрд░ рд╕реНрдкрд╖реНрдЯ рд╣реЛ рдЧрдпрд╛ рд╣реИред
рдирд┐рд╖реНрдкрд╛рджрди рд╕рдордп рдирд╣реАрдВ рдмрджрд▓рд╛ рд╣реИ, рдЬреЛ рддрд░реНрдХрд╕рдВрдЧрдд рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рдЕрдиреБрд░реЛрдзреЛрдВ рдХреА рд╕рдВрдЦреНрдпрд╛ рд╕рдорд╛рди рд╣реИред рд╕реИрджреНрдзрд╛рдВрддрд┐рдХ рд░реВрдк рд╕реЗ рд╕рдВрднрд╡ рдорд╛рдорд▓реЗ рд╣реИрдВ рдЬрдм рд╕реНрдХреЗрд▓рд┐рдВрдЧ рдИрдорд╛рдирджрд╛рд░ рд░рд┐рд╡рд░реНрд╕ рдЗрдВрдЬреАрдирд┐рдпрд░рд┐рдВрдЧ (рдХреЗрд╡рд▓ рдЬрдЯрд┐рд▓ рдЧрдгрдирд╛ рдХреЗ рд▓рд┐рдВрдХ рдХреЛ рд╣рдЯрд╛рдиреЗ рдХреЗ рдХрд╛рд░рдг) рд╕реЗ рдмреЗрд╣рддрд░ рд╣реЛрдЧреАред рд╣рд╛рд▓рд╛рдВрдХрд┐, рд╡рд┐рдкрд░реАрдд рдкрд░рд┐рд╕реНрдерд┐рддрд┐рдпрд╛рдВ рд╕рдорд╛рди рд░реВрдк рд╕реЗ рд╕рдВрднрд╡ рд╣реИрдВ: рдЙрддреНрддрд░рд╛рдзрд┐рдХрд╛рд░ рдкрдВрдХреНрддрд┐ рдмрд╣реБрдд рдЕрдзрд┐рдХ рд╣реИред рдЬреИрд╕рд╛ рдХрд┐ рдЕрднреНрдпрд╛рд╕ рд╕реЗ рдкрддрд╛ рдЪрд▓рддрд╛ рд╣реИ, рдпрджрд┐ рдЖрдк рдкрд░реНрдпрд╛рдкреНрдд рдЙрддреНрддрд░рд╛рдзрд┐рдХрд╛рд░ рдХреЗ рд╕рд╛рде рдЖрдиреЗ рдХрд╛ рдкреНрд░рдмрдВрдзрди рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рдирд┐рд╖реНрдкрд╛рджрди рд╕рдордп рдореЗрдВ рдХреЛрдИ рд╡рд┐рд╢реЗрд╖ рдкрд░рд┐рд╡рд░реНрддрди рдирд╣реАрдВ рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдПред
рд╣рд╛рд▓рд╛рдБрдХрд┐, рдпрд╣ рд╕рдм рдирд╣реАрдВ рд╣реИред рд╣рдордиреЗ рдЗрд╕ рдмрд╛рдд рдкрд░ рдзреНрдпрд╛рди рдирд╣реАрдВ рджрд┐рдпрд╛ рдХрд┐ рдЕрдм рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛рдУрдВ рдФрд░ рдлрд╝рд╛рдЗрд▓реЛрдВ рдкрд░ рд╡рд┐рд╕реНрддреГрдд рдбреЗрдЯрд╛ рдкреНрд░рд╛рдкреНрдд рдХрд░рдирд╛ рд╕рдВрджреЗрд╢реЛрдВ рдХреЛ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рд╕реЗ рд╕рдВрдмрдВрдзрд┐рдд рдирд╣реАрдВ рд╣реИ рдФрд░ рдЕрдиреБрд░реЛрдзреЛрдВ рдХреЛ рд╕рдорд╛рдирд╛рдВрддрд░ рдореЗрдВ рд▓реЙрдиреНрдЪ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ:
рдпрд╣ рд╡рд┐рдХрд▓реНрдк рдПрдХ рд╕реНрдерд┐рд░ 100 ms рдкреНрд░рддрд┐ рдЕрдиреБрд░реЛрдз рджреЗрддрд╛ рд╣реИред
рд╣реНрдпреВрд░рд┐рд╕реНрдЯрд┐рдХ рдПрд░рд░реНрд╕рдХреНрдпрд╛ рд╣реЛрдЧрд╛ рдпрджрд┐, рд╣реЗрдпреБрд░рд┐рд╕реНрдЯрд┐рдХреНрд╕ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╕рдордп, рдкреНрд░рд╢реНрдиреЛрдВ рдХрд╛ рд╕реЗрдЯ рдмрдбрд╝рд╛ рдирд╣реАрдВ рд╣реИ, рд▓реЗрдХрд┐рди рдЗрд╕рд╕реЗ рдЫреЛрдЯрд╛ рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдП? рдЕрдзрд┐рдХрд╛рдВрд╢ рд╡рд┐рдХрд▓реНрдкреЛрдВ рдХреЗ рд▓рд┐рдП, рдРрд╕реЗ рдЖрдВрдХрдбрд╝реЗ рдХрд╛рдо рдХрд░реЗрдВрдЧреЗ, рд▓реЗрдХрд┐рди рдРрд╕реЗ рдЕрдкрд╡рд╛рдж рд╣реЛрдВрдЧреЗ рдЬрд┐рдирдХреЗ рд▓рд┐рдП рдЖрдкрдХреЛ рдПрдХ рдЕрд▓рдЧ рдЕрдиреБрд░реЛрдз рдХрд░рдирд╛ рд╣реЛрдЧрд╛ред рдореЗрд░реЗ рд╡реНрдпрд╡рд╣рд╛рд░ рдореЗрдВ, рдЗрд╕ рддрд░рд╣ рдХреЗ рдирд┐рд░реНрдгрдп рдЕрд╕рдлрд▓ рдереЗ, рдХреНрдпреЛрдВрдХрд┐ рдкреНрд░рддреНрдпреЗрдХ рдЕрдкрд╡рд╛рдж рдХрд╛ рдкреНрд░рджрд░реНрд╢рди рдкрд░ рдПрдХ рдмрдбрд╝рд╛ рдкреНрд░рднрд╛рд╡ рдерд╛, рдФрд░ рдЕрдВрдд рдореЗрдВ рдХреБрдЫ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдиреЗ рдПрдХ рдЕрдиреБрд░реЛрдз рдХрд┐рдпрд╛ рдЬрд┐рд╕рдореЗрдВ рдкреВрд░реА рддрд░рд╣ рд╕реЗ рдЕрдкрд╡рд╛рдж рд╢рд╛рдорд┐рд▓ рдереЗред рдореИрдВ рдХрд╣реВрдВрдЧрд╛ рдХрд┐ рдРрд╕реА рд╕реНрдерд┐рддрд┐рдпреЛрдВ рдореЗрдВ, рд░рд┐рд╡рд░реНрд╕ рдЗрдВрдЬреАрдирд┐рдпрд░рд┐рдВрдЧ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рдмреЗрд╣рддрд░ рд╣реИ, рднрд▓реЗ рд╣реА рдХреНрд╡реЗрд░реА рд╕рдВрдЧреНрд░рд╣ рдПрд▓реНрдЧреЛрд░рд┐рдереНрдо рдбрд░рд╛рд╡рдирд╛ рдФрд░ рдЕрдкрдардиреАрдп рд╣реЛ, рд▓реЗрдХрд┐рди, рдирд┐рд╢реНрдЪрд┐рдд рд░реВрдк рд╕реЗ, рдпрд╣ рд╕рдм рд╕реЗрд╡рд╛ рдХреА рдорд╣рддреНрд╡рдкреВрд░реНрдгрддрд╛ рдкрд░ рдирд┐рд░реНрднрд░ рдХрд░рддрд╛ рд╣реИред
рдирд┐рд╖реНрдХрд░реНрд╖рдкреЗрд╢реЗрд╡рд░реЛрдВ:
- рд╡реНрдпрд╛рдкрд╛рд░ рдХреЗ рдЖрдВрдХрдбрд╝реЛрдВ рдХреЗ рддрд░реНрдХ рдХреЛ рдкрдврд╝рдирд╛ рдЖрд╕рд╛рди рд╣реИ рдФрд░ рдЖрдорддреМрд░ рдкрд░ рддреБрдЪреНрдЫ рд╣реИред рдпрд╣ рдкреНрд░рдпреЛрдЬреНрдпрддрд╛ рдХреА рд╕реАрдорд╛рдУрдВ рдХреЛ рд╕рдордЭрдиреЗ, рдкреНрд░реАрдлреИрдЪ рдЕрдиреБрдмрдВрдз рдХреЛ рд╕рддреНрдпрд╛рдкрд┐рдд рдХрд░рдиреЗ рдФрд░ рд╕рдВрд╢реЛрдзрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЕрдЪреНрдЫрд╛ рд╣реИред
- рд╕реНрдХреЗрд▓реЗрдмрд┐рд▓рд┐рдЯреА рд░рд┐рд╡рд░реНрд╕ рдЗрдВрдЬреАрдирд┐рдпрд░рд┐рдВрдЧ рдЬрд┐рддрдиреА рд╣реА рдЕрдЪреНрдЫреА рд╣реИред
- рдбреЗрдЯрд╛ рдХреЗ рдЕрдиреБрд╕рд╛рд░ рдХреЛрдб рдХрд╛ рд╕рд╛рдордВрдЬрд╕реНрдп рдХрдо рд╣реЛ рдЬрд╛рддрд╛ рд╣реИ, рдЬрд┐рд╕рд╕реЗ рдХреЛрдб рдХрд╛ рдмреЗрд╣рддрд░ рд╕рдорд╛рдирд╛рдВрддрд░рдХрд░рдг рд╣реЛ рд╕рдХрддрд╛ рд╣реИред
- рдкреНрд░реАрд╕реНрдЯреЗрдХ рддрд░реНрдХ, REST рдирд┐рдпрдВрддреНрд░рдХ рдХреЗ рдореБрдЦреНрдп рддрд░реНрдХ рдХреА рддрд░рд╣, рдЖрд╡рд╢реНрдпрдХрддрд╛рдУрдВ рдкрд░ рдЖрдзрд╛рд░рд┐рдд рд╣реИред рдпрд╣ рдПрдХ рдХрдордЬреЛрд░ рдкреНрд▓рд╕ рд╣реИ рдЕрдЧрд░ рдЖрд╡рд╢реНрдпрдХрддрд╛рдПрдВ рдЕрдХреНрд╕рд░ рдмрджрд▓рддреА рд╣реИрдВред
рд╡рд┐рдкрдХреНрд╖:
- рдЖрд╡рд╢реНрдпрдХрддрд╛рдУрдВ рд╕реЗ рдХреНрд╡реЗрд░реА рдЕрдиреБрдорд╛рдиреЛрдВ рдХреЗ рд▓рд┐рдП рдЕрдиреБрдорд╛рдиреЛрдВ рдХреЛ рдкреНрд░рд╛рдкреНрдд рдХрд░рдирд╛ рдЗрддрдирд╛ рдЖрд╕рд╛рди рдирд╣реАрдВ рд╣реИред рдЖрд╡рд╢реНрдпрдХрддрд╛рдУрдВ рдХрд╛ рд╕рд░рд▓реАрдХрд░рдг рдЖрд╡рд╢реНрдпрдХ рд╣реЛ рд╕рдХрддрд╛ рд╣реИ, рдЙрд╕ рд╕реАрдорд╛ рддрдХ рдЬреЛ рдЪреБрд╕реНрдд рдХреЗ рд╕рд╛рде рдЦрд░рд╛рдм рд░реВрдк рд╕реЗ рд╕рдВрдЧрдд рд╣реИред
- рдЖрдк рдЕрддрд┐рд░рд┐рдХреНрдд рдбреЗрдЯрд╛ рдкреНрд░рд╛рдкреНрдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред
- рдпрд╣ рд╕реБрдирд┐рд╢реНрдЪрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐ рдкреНрд░реАрдлреИрдЪ рдХреЙрдиреНрдЯреНрд░реИрдХреНрдЯ рдкреНрд░рднрд╛рд╡реА рд░реВрдк рд╕реЗ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ, рд╕рдВрднрд╡рддрдГ рдбреЗрдЯрд╛ рд╕реНрдЯреЛрд░реЗрдЬ рдХрд╛ рд╡рд┐рдХреЗрдВрджреНрд░реАрдХрд░рдг рдЖрд╡рд╢реНрдпрдХ рд╣реЛрдЧрд╛ред , - , , .
, . - - , . , , .
. - , .
DDD
DDD, . DDD тАФ . DDD, . , ( , ).
, тАФ . , :
- . .
- . .
, prefetch . prefetch -, . , (-), , .
, ┬л┬╗. ChatMessage, UserReference, FileReference , - , , . Chat, тАФ ChatPage ChatPageMessage:
interface Chat {
fun getLastPage ( n : Int ) : ChatPage
}
interface ChatPage {
val messages : List < ChatPageMessage >
}
data class ChatPageMessage (
val id : Long ,
val author : UserRemote ,
val message : String ,
val files : List < FileHeadRemote >,
val replyTo : ChatPageMessage ? ,
val forwardFrom : ChatPageMessage ?
)
. , .
FileHeadRemote UserRemote , , .
, REST- :
class ChatRestController (
private val chat : Chat
) : ChatRestApi {
override fun getLast ( n : Int ) =
chat . getLastPage ( n ) . toFrontModel ()
private fun ChatPage . toFrontModel () =
messages . map { it . toFrontModel () }
private fun ChatPageMessage . toFrontModel () : ChatMessageUI =
ChatMessageUI (
id = id ,
author = author . toFrontReference () ,
message = message ,
files = files . toFrontReference () ,
forwardFrom = forwardFrom ?. toFrontModel () ,
replyTo = replyTo ?. toFrontModel ()
)
}
, : , , , . , prefetch . , (Single Responsibility Principle, SRP).
, .
, -.class ChatImpl (
private val messageRepository : ChatMessageRepository ,
private val userRepository : UserRemoteApi ,
private val fileRepository : FileRemoteApi
) : Chat {
override fun getLastPage ( n : Int ) = object : ChatPage {
override val messages : List < ChatPageMessage >
get () =
runBlocking ( IO ) {
val prefetch = async (
{ userRepository . getUsersByChat () . associateBy { it . id } } ,
{ fileRepository . getHeadsByChat () . associateBy { it . id } }
)
withContext ( IO ) { messageRepository . findLast ( n ) }
. map (
prefetch . await () . let { ( users , files ) ->
recursiveMemoize { message , memoized : ( ChatMessage ) -> ChatPageMessage ->
message . toDomainModel (
getUser = users ::get . orThrow { IllegalArgumentException ( "User $ it " ) } ,
getFile = files ::get . orThrow { IllegalArgumentException ( "File $ it " ) } ,
//
serializeMessage = memoized
)
}
}
)
}
}
}
private fun ChatMessage . toDomainModel (
getUser : ( UserReference ) -> UserRemote ,
getFile : ( FileReference ) -> FileHeadRemote ,
serializeMessage : ( ChatMessage ) -> ChatPageMessage
) = ChatPageMessage (
id = id ?: throw IllegalStateException ( " $ this must be persisted" ) ,
author = getUser ( author ) ,
message = message ,
files = files ?. map ( getFile ) ?: listOf () ,
forwardFrom = forwardFrom ?. let ( serializeMessage ) ,
replyTo = replyTo ?. let ( serializeMessage )
)
, getLastPage , prefetch, toDomainModel .
userRepository, fileRepository messageRepository Kotlin . , - .
, , - -.
: ChatPage Chat, getLast(), . :
interface Chat {
fun getPage () : ChatPage
}
, Chat ChatPage:
class ChatPageImpl (
private val messageData : List < ChatMessage >,
private val userData : List < UserRemote >,
private val fileData : List < FileHeadRemote >
) : ChatPage {
override val messages : List < ChatPageMessage >
get () =
messageData . map (
( userData . associateBy { it . id } to fileData . associateBy { it . id } )
. let { ( users , files ) ->
recursiveMemoize { message , self : ( ChatMessage ) -> ChatPageMessage ->
message . toDomainModel (
getUser = users ::get . orThrow () ,
getFile = files ::get . orThrow () ,
//
serializeMessage = self
)
}
}
)
}
prefetch, :
fun chatPagePrefetch (
pageSize : Int ,
messageRepository : ChatMessageRepository ,
userRepository : UserRemoteApi ,
fileRepository : FileRemoteApi
) =
runBlocking ( IO ) {
async (
{ userRepository . getUsersByChat () } ,
{ fileRepository . getHeadsByChat () } ,
{ messageRepository . findLast ( pageSize ) }
)
}
, , prefetch. DDD Application Services.
class ChatService (
private val messageRepository : ChatMessageRepository ,
private val userRepository : UserRemoteApi ,
private val fileRepository : FileRemoteApi
) {
private fun chatPagePrefetch ( pageSize : Int ) =
runBlocking ( IO ) {
async (
{ messageRepository . findLast ( pageSize ) } ,
{ userRepository . getUsersByChat () } ,
{ fileRepository . getHeadsByChat () }
) . await ()
}
fun getLastPage ( n : Int ) : ChatPage =
chatPagePrefetch ( n )
. let { ( messageData , userData , fileData ) ->
ChatPageImpl ( messageData , userData , fileData )
}
}
, Chat::getLastPage ChatService::getLastPage. :
class ChatRestController (
private val chat : ChatService
) : ChatRestApi
рдирд┐рд╖реНрдХрд░реНрд╖- prefetch , .
- prefetch , , . prefetch , .
- , prefetch .
prefetch, .
, prefetch , , . , , . , - ? , . , Mockito, , .
.
, .
: . , - , .
, messageRepository, . , messageRepository , .
UserReference->UserRemote FileReference->FileHeadRemote, .
:class ChatRestController (
private val messageRepository : ChatMessageRepository ,
private val userRepository : UserRemoteApi ,
private val fileRepository : FileRemoteApi
) : ChatRestApi {
override fun getLast ( n : Int ) : List < ChatMessageUI > {
val messages = messageRepository . findLast ( n )
//
fun transform (
getUser : ( UserReference ) -> UserRemote ,
getFile : ( FileReference ) -> FileHeadRemote
) : List < ChatMessageUI > =
messages . map (
recursiveMemoize { message , self ->
message . toFrontModel ( getUser , getFile , self )
}
)
//
val userIds = mutableSetOf < UserReference > ()
val fileIds = mutableSetOf < FileReference > ()
transform (
{ userIds += it ; UserRemote ( 0L , "" ) } ,
{ fileIds += it ; FileHeadRemote ( 0L , "" ) }
)
return runBlocking ( IO ) {
//
async (
{ userRepository . getUsersByIds ( userIds ) . associateBy { it . id } ::get . orThrow () } ,
{ fileRepository . getHeadsByIds ( fileIds ) . associateBy { it . id } ::get . orThrow () }
) . await () . let { ( getUser , getFile ) ->
transform ( getUser , getFile )
}
}
}
}
, , , -, . , , ( ).
-, . , . , , , , - .
рдирд┐рд╖реНрдХрд░реНрд╖рдкреЗрд╢реЗрд╡рд░реЛрдВ:
- prefetch - .
- prefetch.
- , -.
рд╡рд┐рдкрдХреНрд╖:
- .
- , .
, , . , -: , ( , ).
, prefetch .
, - , prefetch .
рдирд┐рд╖реНрдХрд░реНрд╖
, . , ( ).
, . : ( , ), , , .
тАФ - . . тАФ - , , . , , , , .
тАФ . , . .