āĻĒā§āĻ°āĻžāĻ¯āĻŧ āĻ¸āĻŽāĻ¸ā§āĻ¤ āĻāĻ§ā§āĻ¨āĻŋāĻ āĻ¸āĻĢā§āĻāĻāĻ¯āĻŧā§āĻ¯āĻžāĻ° āĻĒāĻŖā§āĻ¯ āĻŦāĻŋāĻāĻŋāĻ¨ā§āĻ¨ āĻĒāĻ°āĻŋāĻˇā§āĻŦāĻž āĻ¨āĻŋāĻ¯āĻŧā§ āĻāĻ āĻŋāĻ¤āĨ¤ āĻĒā§āĻ°āĻžāĻ¯āĻŧāĻļāĻ, āĻāĻ¨ā§āĻāĻžāĻ°āĻ¸āĻžāĻ°ā§āĻāĻŋāĻ¸ āĻā§āĻ¯āĻžāĻ¨ā§āĻ˛āĻā§āĻ˛āĻŋāĻ° āĻĻā§āĻ°ā§āĻ āĻĒā§āĻ°āĻ¤āĻŋāĻā§āĻ°āĻŋāĻ¯āĻŧāĻž āĻ¸āĻŽāĻ¯āĻŧāĻā§āĻ˛āĻŋ āĻāĻ°ā§āĻŽāĻā§āĻˇāĻŽāĻ¤āĻž āĻ¸āĻŽāĻ¸ā§āĻ¯āĻžāĻ° āĻāĻ¤ā§āĻ¸ āĻšāĻ¯āĻŧā§ āĻāĻ ā§āĨ¤ āĻāĻ āĻ§āĻ°āĻ¨ā§āĻ° āĻ¸āĻŽāĻ¸ā§āĻ¯āĻžāĻ° āĻāĻĻāĻ°ā§āĻļ āĻ¸āĻŽāĻžāĻ§āĻžāĻ¨ āĻšāĻ˛ āĻāĻāĻžāĻ§āĻŋāĻ āĻāĻ¨ā§āĻāĻžāĻ°āĻ¸āĻžāĻ°ā§āĻāĻŋāĻ¸ āĻ āĻ¨ā§āĻ°ā§āĻ§āĻā§āĻ˛āĻŋāĻā§ āĻāĻāĻāĻŋ āĻĒā§āĻ¯āĻžāĻā§āĻā§ āĻĒā§āĻ¯āĻžāĻ āĻāĻ°āĻž, āĻ¯āĻžāĻā§ āĻŦā§āĻ¯āĻžāĻāĻŋāĻ āĻŦāĻ˛āĻž āĻšāĻ¯āĻŧāĨ¤
āĻāĻĒāĻ¨āĻŋ āĻ¯āĻĻāĻŋ āĻŦā§āĻ¯āĻžāĻ āĻĒā§āĻ°āĻ¸ā§āĻ¸āĻŋāĻ āĻŦā§āĻ¯āĻŦāĻšāĻžāĻ° āĻāĻ°ā§āĻ¨, āĻ¤āĻžāĻšāĻ˛ā§ āĻāĻĒāĻ¨āĻŋ āĻāĻ°ā§āĻŽāĻā§āĻˇāĻŽāĻ¤āĻž āĻŦāĻž āĻā§āĻĄ āĻ¸ā§āĻĒāĻˇā§āĻāĻ¤āĻžāĻ° āĻĒāĻ°āĻŋāĻĒā§āĻ°ā§āĻā§āĻˇāĻŋāĻ¤ā§ āĻĢāĻ˛āĻžāĻĢāĻ˛ā§ āĻā§āĻļāĻŋ āĻ¨āĻžāĻ āĻšāĻ¤ā§ āĻĒāĻžāĻ°ā§āĻ¨āĨ¤ āĻāĻ āĻĒāĻĻā§āĻ§āĻ¤āĻŋāĻāĻŋ āĻāĻ˛āĻžāĻ°ā§āĻ° āĻāĻ¨ā§āĻ¯ āĻ¤āĻ¤āĻāĻž āĻ¸āĻšāĻ āĻ¨āĻ¯āĻŧ āĻ¯āĻ¤āĻāĻž āĻāĻĒāĻ¨āĻŋ āĻāĻžāĻŦāĻ¤ā§ āĻĒāĻžāĻ°ā§āĻ¨āĨ¤ āĻŦāĻŋāĻāĻŋāĻ¨ā§āĻ¨ āĻāĻĻā§āĻĻā§āĻļā§āĻ¯ā§ āĻāĻŦāĻ āĻŦāĻŋāĻāĻŋāĻ¨ā§āĻ¨ āĻĒāĻ°āĻŋāĻ¸ā§āĻĨāĻŋāĻ¤āĻŋāĻ¤ā§, āĻ¸āĻŽāĻžāĻ§āĻžāĻ¨āĻā§āĻ˛āĻŋ āĻŦā§āĻ¯āĻžāĻĒāĻāĻāĻžāĻŦā§ āĻĒāĻ°āĻŋāĻŦāĻ°ā§āĻ¤āĻŋāĻ¤ āĻšāĻ¤ā§ āĻĒāĻžāĻ°ā§āĨ¤ āĻ¨āĻŋāĻ°ā§āĻĻāĻŋāĻˇā§āĻ āĻāĻĻāĻžāĻšāĻ°āĻŖ āĻŦā§āĻ¯āĻŦāĻšāĻžāĻ° āĻāĻ°ā§, āĻāĻŽāĻŋ āĻŦāĻŋāĻāĻŋāĻ¨ā§āĻ¨ āĻĒāĻĻā§āĻ§āĻ¤āĻŋāĻ° āĻ¸ā§āĻŦāĻŋāĻ§āĻž āĻāĻŦāĻ āĻ
āĻ¸ā§āĻŦāĻŋāĻ§āĻž āĻĻā§āĻāĻžāĻŦāĨ¤
āĻĒā§āĻ°āĻĻāĻ°ā§āĻļāĻ¨ā§ āĻĒā§āĻ°āĻāĻ˛ā§āĻĒ
āĻ¸ā§āĻĒāĻˇā§āĻāĻ¤āĻžāĻ° āĻāĻ¨ā§āĻ¯, āĻāĻŽāĻŋ āĻŦāĻ°ā§āĻ¤āĻŽāĻžāĻ¨ā§ āĻ¯ā§ āĻ ā§āĻ¯āĻžāĻĒā§āĻ˛āĻŋāĻā§āĻļāĻ¨āĻāĻŋāĻ¤ā§ āĻāĻžāĻ āĻāĻ°āĻāĻŋ āĻ¤āĻžāĻ° āĻāĻāĻāĻŋ āĻĒāĻ°āĻŋāĻˇā§āĻŦāĻžāĻ° āĻāĻĻāĻžāĻšāĻ°āĻŖ āĻĻā§āĻāĻŋāĨ¤
āĻāĻĻāĻžāĻšāĻ°āĻŖā§āĻ° āĻāĻ¨ā§āĻ¯ āĻĒā§āĻ˛ā§āĻ¯āĻžāĻāĻĢāĻ°ā§āĻŽ āĻ¨āĻŋāĻ°ā§āĻŦāĻžāĻāĻ¨ā§āĻ° āĻŦā§āĻ¯āĻžāĻā§āĻ¯āĻžāĻĻā§āĻ°ā§āĻŦāĻ˛ āĻĒāĻžāĻ°āĻĢāĻ°āĻŽā§āĻ¯āĻžāĻ¨ā§āĻ¸ā§āĻ° āĻ¸āĻŽāĻ¸ā§āĻ¯āĻžāĻāĻŋ āĻŦā§āĻļ āĻ¸āĻžāĻ§āĻžāĻ°āĻŖ āĻāĻŦāĻ āĻā§āĻ¨āĻ āĻ¨āĻŋāĻ°ā§āĻĻāĻŋāĻˇā§āĻ āĻāĻžāĻˇāĻž āĻŦāĻž āĻĒā§āĻ˛ā§āĻ¯āĻžāĻāĻĢāĻ°ā§āĻŽāĻā§ āĻĒā§āĻ°āĻāĻžāĻŦāĻŋāĻ¤ āĻāĻ°ā§ āĻ¨āĻžāĨ¤ āĻāĻ āĻ¨āĻŋāĻŦāĻ¨ā§āĻ§āĻāĻŋ āĻ¸āĻŽāĻ¸ā§āĻ¯āĻž āĻāĻŦāĻ āĻ¸āĻŽāĻžāĻ§āĻžāĻ¨ āĻĒā§āĻ°āĻĻāĻ°ā§āĻļāĻ¨ āĻāĻ°āĻ¤ā§ āĻ¸ā§āĻĒā§āĻ°āĻŋāĻ + āĻā§āĻāĻ˛āĻŋāĻ¨ āĻā§āĻĄ āĻāĻĻāĻžāĻšāĻ°āĻŖ āĻŦā§āĻ¯āĻŦāĻšāĻžāĻ° āĻāĻ°āĻŦā§āĨ¤ Kotlin āĻāĻžāĻāĻž āĻāĻŦāĻ C# āĻĄā§āĻā§āĻ˛āĻĒāĻžāĻ°āĻĻā§āĻ° āĻāĻ¨ā§āĻ¯ āĻ¸āĻŽāĻžāĻ¨āĻāĻžāĻŦā§ āĻŦā§āĻ§āĻāĻŽā§āĻ¯ (āĻŦāĻž āĻŦā§āĻ§āĻāĻŽā§āĻ¯), āĻāĻĒāĻ°āĻ¨ā§āĻ¤ā§, āĻā§āĻĄ āĻāĻžāĻāĻžāĻ° āĻ¤ā§āĻ˛āĻ¨āĻžāĻ¯āĻŧ āĻāĻ°ā§ āĻāĻŽāĻĒā§āĻ¯āĻžāĻā§āĻ āĻāĻŦāĻ āĻŦā§āĻ§āĻāĻŽā§āĻ¯āĨ¤ āĻāĻžāĻāĻāĻŋ āĻāĻžāĻāĻž āĻĄā§āĻā§āĻ˛āĻĒāĻžāĻ°āĻĻā§āĻ° āĻāĻ¨ā§āĻ¯ āĻŦā§āĻāĻž āĻ¸āĻšāĻ āĻāĻ°āĻžāĻ° āĻāĻ¨ā§āĻ¯, āĻāĻŽāĻŋ āĻā§āĻāĻ˛āĻŋāĻ¨ā§āĻ° āĻāĻžāĻ˛ā§ āĻāĻžāĻĻā§ āĻāĻĄāĻŧāĻžāĻŦ āĻāĻŦāĻ āĻļā§āĻ§ā§āĻŽāĻžāĻ¤ā§āĻ° āĻ¸āĻžāĻĻāĻž āĻāĻžāĻĻā§ āĻŦā§āĻ¯āĻŦāĻšāĻžāĻ° āĻāĻ°āĻŦ (āĻ˛āĻŽā§āĻŦāĻā§āĻ° āĻā§āĻ¤āĻ¨āĻžāĻ¯āĻŧ)āĨ¤ āĻāĻ¯āĻŧā§āĻāĻāĻŋ āĻāĻā§āĻ¸āĻā§āĻ¨āĻļāĻ¨ āĻĒāĻĻā§āĻ§āĻ¤āĻŋ āĻĨāĻžāĻāĻŦā§, āĻ¤āĻŦā§ āĻ¤āĻžāĻ°āĻž āĻĒā§āĻ°āĻā§āĻ¤āĻĒāĻā§āĻˇā§ āĻ¸āĻŽāĻ¸ā§āĻ¤ āĻāĻžāĻāĻž āĻĒā§āĻ°ā§āĻā§āĻ°āĻžāĻŽāĻžāĻ°āĻĻā§āĻ° āĻāĻžāĻā§ āĻ¸ā§āĻā§āĻ¯āĻžāĻāĻŋāĻ āĻĒāĻĻā§āĻ§āĻ¤āĻŋ āĻšāĻŋāĻ¸āĻžāĻŦā§ āĻĒāĻ°āĻŋāĻāĻŋāĻ¤, āĻ¤āĻžāĻ āĻāĻāĻŋ āĻāĻāĻāĻŋ āĻā§āĻ āĻāĻŋāĻ¨āĻŋ āĻ¯āĻž āĻāĻžāĻŦāĻžāĻ°ā§āĻ° āĻ¸ā§āĻŦāĻžāĻĻ āĻ¨āĻˇā§āĻ āĻāĻ°āĻŦā§ āĻ¨āĻžāĨ¤
āĻāĻāĻāĻŋ āĻ¨āĻĨāĻŋ āĻ
āĻ¨ā§āĻŽā§āĻĻāĻ¨ āĻ¸ā§āĻŦāĻž āĻāĻā§. āĻā§āĻ āĻāĻāĻāĻŋ āĻ¨āĻĨāĻŋ āĻ¤ā§āĻ°āĻŋ āĻāĻ°ā§ āĻāĻŦāĻ āĻāĻ˛ā§āĻāĻ¨āĻžāĻ° āĻāĻ¨ā§āĻ¯ āĻāĻŽāĻž āĻĻā§āĻ¯āĻŧ, āĻ¯āĻžāĻ° āĻ¸āĻŽāĻ¯āĻŧ āĻ¸āĻŽā§āĻĒāĻžāĻĻāĻ¨āĻž āĻāĻ°āĻž āĻšāĻ¯āĻŧ, āĻāĻŦāĻ āĻļā§āĻˇ āĻĒāĻ°ā§āĻ¯āĻ¨ā§āĻ¤ āĻ¨āĻĨāĻŋāĻ¤ā§ āĻ¸āĻŽā§āĻŽāĻ¤ āĻšāĻ¯āĻŧāĨ¤ āĻ
āĻ¨ā§āĻŽā§āĻĻāĻ¨ āĻĒāĻ°āĻŋāĻˇā§āĻŦāĻž āĻ¨āĻŋāĻā§āĻ āĻ¨āĻĨāĻŋ āĻ¸āĻŽā§āĻĒāĻ°ā§āĻā§ āĻāĻŋāĻā§āĻ āĻāĻžāĻ¨ā§ āĻ¨āĻž: āĻāĻāĻŋ āĻā§āĻŦāĻ˛āĻŽāĻžāĻ¤ā§āĻ° āĻā§āĻ āĻ
āĻ¤āĻŋāĻ°āĻŋāĻā§āĻ¤ āĻĢāĻžāĻāĻļāĻ¨ āĻ¸āĻš āĻ
āĻ¨ā§āĻŽā§āĻĻāĻ¨āĻāĻžāĻ°ā§āĻĻā§āĻ° āĻāĻāĻāĻŋ āĻā§āĻ¯āĻžāĻ āĻ¯āĻž āĻāĻŽāĻ°āĻž āĻāĻāĻžāĻ¨ā§ āĻŦāĻŋāĻŦā§āĻāĻ¨āĻž āĻāĻ°āĻŦ āĻ¨āĻžāĨ¤
āĻ¸ā§āĻ¤āĻ°āĻžāĻ, āĻ¤āĻžāĻĻā§āĻ° āĻĒā§āĻ°āĻ¤ā§āĻ¯ā§āĻāĻāĻŋāĻ¤ā§ āĻ āĻāĻļāĻā§āĻ°āĻšāĻŖāĻāĻžāĻ°ā§āĻĻā§āĻ° āĻāĻāĻāĻŋ āĻĒā§āĻ°ā§āĻŦāĻ¨āĻŋāĻ°ā§āĻ§āĻžāĻ°āĻŋāĻ¤ āĻ¸ā§āĻ āĻ¸āĻš āĻā§āĻ¯āĻžāĻ āĻ°ā§āĻŽ (āĻ¨āĻĨāĻŋāĻ° āĻ¸āĻžāĻĨā§ āĻ¸āĻŽā§āĻĒāĻ°ā§āĻāĻŋāĻ¤) āĻ°āĻ¯āĻŧā§āĻā§āĨ¤ āĻ¨āĻŋāĻ¯āĻŧāĻŽāĻŋāĻ¤ āĻā§āĻ¯āĻžāĻā§āĻ° āĻŽāĻ¤ā§, āĻŦāĻžāĻ°ā§āĻ¤āĻžāĻā§āĻ˛āĻŋāĻ¤ā§ āĻĒāĻžāĻ ā§āĻ¯ āĻāĻŦāĻ āĻĢāĻžāĻāĻ˛ āĻĨāĻžāĻā§ āĻāĻŦāĻ āĻāĻ¤ā§āĻ¤āĻ° āĻŦāĻž āĻĢāĻ°ā§āĻ¯āĻŧāĻžāĻ°ā§āĻĄ āĻšāĻ¤ā§ āĻĒāĻžāĻ°ā§:
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
āĻŦā§āĻ¯āĻŦāĻšāĻžāĻ°āĻāĻžāĻ°ā§āĻ° āĻĄā§āĻāĻž āĻā§āĻā§āĻ˛ā§āĻā§ āĻ¸āĻāĻ°āĻā§āĻˇāĻŖ āĻāĻ°āĻž āĻšāĻ¯āĻŧ āĻāĻŦāĻ REST āĻāĻ° āĻŽāĻžāĻ§ā§āĻ¯āĻŽā§ āĻĒā§āĻ¨āĻ°ā§āĻĻā§āĻ§āĻžāĻ° āĻāĻ°āĻž āĻšāĻ¯āĻŧāĨ¤ āĻĢāĻžāĻāĻ˛āĻā§āĻ˛āĻŋāĻ° āĻā§āĻˇā§āĻ¤ā§āĻ°ā§āĻ āĻāĻāĻ āĻ°āĻāĻŽ āĻšāĻ¯āĻŧ: āĻĢāĻžāĻāĻ˛ āĻāĻŦāĻ āĻ¸ā§āĻā§āĻ˛āĻŋāĻ° āĻ¸āĻŽā§āĻĒāĻ°ā§āĻā§ āĻ¤āĻĨā§āĻ¯ āĻāĻāĻāĻŋ āĻĒā§āĻĨāĻ āĻĢāĻžāĻāĻ˛ āĻ¸ā§āĻā§āĻ°ā§āĻ āĻĒāĻ°āĻŋāĻˇā§āĻŦāĻžāĻ¤ā§ āĻĨāĻžāĻā§ā§ˇ
āĻāĻ āĻĒāĻ°āĻŋāĻˇā§āĻŦāĻžāĻā§āĻ˛āĻŋāĻ¤ā§ āĻ¸āĻŽāĻ¸ā§āĻ¤ āĻāĻ˛ āĻšāĻ¯āĻŧ āĻāĻžāĻ°ā§ āĻ āĻ¨ā§āĻ°ā§āĻ§. āĻāĻ° āĻŽāĻžāĻ¨ā§ āĻšāĻ˛ āĻ¯ā§ āĻāĻ āĻ āĻ¨ā§āĻ°ā§āĻ§āĻā§āĻ˛āĻŋ āĻĒāĻ°āĻŋāĻŦāĻšāĻ¨ā§āĻ° āĻāĻāĻžāĻ°āĻšā§āĻĄ āĻāĻāĻāĻŋ āĻ¤ā§āĻ¤ā§āĻ¯āĻŧ āĻĒāĻā§āĻˇā§āĻ° āĻĒāĻ°āĻŋāĻˇā§āĻŦāĻž āĻĻā§āĻŦāĻžāĻ°āĻž āĻĒā§āĻ°āĻā§āĻ°āĻŋāĻ¯āĻŧāĻžāĻāĻ°āĻŖā§āĻ° āĻāĻ¨ā§āĻ¯ āĻ¯ā§ āĻ¸āĻŽāĻ¯āĻŧ āĻ˛āĻžāĻā§ āĻ¤āĻžāĻ° āĻā§āĻ¯āĻŧā§ āĻ āĻ¨ā§āĻ āĻŦā§āĻļāĻŋāĨ¤ āĻāĻŽāĻžāĻĻā§āĻ° āĻĒāĻ°ā§āĻā§āĻˇāĻžāĻ° āĻŦā§āĻā§āĻāĻā§āĻ˛āĻŋāĻ¤ā§, āĻāĻ āĻ§āĻ°āĻ¨ā§āĻ° āĻĒāĻ°āĻŋāĻˇā§āĻŦāĻžāĻā§āĻ˛āĻŋāĻ° āĻāĻ¨ā§āĻ¯ āĻ¸āĻžāĻ§āĻžāĻ°āĻŖ āĻāĻ˛ āĻāĻžāĻāĻŽ āĻšāĻ˛ 100 ms, āĻ¤āĻžāĻ āĻāĻŽāĻ°āĻž āĻāĻŦāĻŋāĻˇā§āĻ¯āĻ¤ā§ āĻāĻ āĻ¨āĻŽā§āĻŦāĻ°āĻā§āĻ˛āĻŋ āĻŦā§āĻ¯āĻŦāĻšāĻžāĻ° āĻāĻ°āĻŦā§ˇ
āĻ¸āĻŽāĻ¸ā§āĻ¤ āĻĒā§āĻ°āĻ¯āĻŧā§āĻāĻ¨ā§āĻ¯āĻŧ āĻ¤āĻĨā§āĻ¯ āĻ¸āĻš āĻļā§āĻˇ āĻāĻ¨ āĻŦāĻžāĻ°ā§āĻ¤āĻžāĻā§āĻ˛āĻŋ āĻĒā§āĻ¤ā§ āĻāĻŽāĻžāĻĻā§āĻ° āĻāĻāĻāĻŋ āĻ¸āĻžāĻ§āĻžāĻ°āĻŖ 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>
}
UI āĻĒā§āĻ¸ā§āĻāĻĢāĻŋāĻā§āĻ¸ āĻŽāĻžāĻ¨ā§ āĻĢā§āĻ°āĻ¨ā§āĻāĻāĻ¨ā§āĻĄā§āĻ° āĻāĻ¨ā§āĻ¯ DTO āĻŽāĻĄā§āĻ˛, āĻ āĻ°ā§āĻĨāĻžā§ REST āĻāĻ° āĻŽāĻžāĻ§ā§āĻ¯āĻŽā§ āĻāĻŽāĻžāĻĻā§āĻ° āĻ¯āĻž āĻĒāĻ°āĻŋāĻŦā§āĻļāĻ¨ āĻāĻ°āĻž āĻāĻāĻŋāĻ¤āĨ¤
āĻāĻāĻžāĻ¨ā§ āĻāĻļā§āĻāĻ°ā§āĻ¯ā§āĻ° āĻŦāĻŋāĻˇāĻ¯āĻŧ āĻšāĻ¤ā§ āĻĒāĻžāĻ°ā§ āĻ¯ā§ āĻāĻŽāĻ°āĻž āĻā§āĻ¨ā§ āĻā§āĻ¯āĻžāĻ āĻāĻāĻĄāĻŋ āĻĒāĻžāĻ¸ āĻāĻ°āĻāĻŋ āĻ¨āĻž āĻāĻŽāĻ¨āĻāĻŋ ChatMessage/ChatMessageUI āĻŽāĻĄā§āĻ˛ā§āĻ° āĻāĻāĻāĻŋāĻ āĻ¨ā§āĻāĨ¤ āĻāĻŽāĻŋ āĻāĻā§āĻāĻžāĻā§āĻ¤āĻāĻžāĻŦā§ āĻāĻāĻŋ āĻāĻ°ā§āĻāĻŋ āĻ¯āĻžāĻ¤ā§ āĻāĻĻāĻžāĻšāĻ°āĻŖāĻā§āĻ˛āĻŋāĻ° āĻā§āĻĄ āĻŦāĻŋāĻļā§āĻā§āĻāĻ˛ āĻ¨āĻž āĻšāĻ¯āĻŧ (āĻā§āĻ¯āĻžāĻāĻā§āĻ˛āĻŋ āĻŦāĻŋāĻā§āĻāĻŋāĻ¨ā§āĻ¨, āĻ¤āĻžāĻ āĻāĻŽāĻ°āĻž āĻ§āĻ°ā§ āĻ¨āĻŋāĻ¤ā§ āĻĒāĻžāĻ°āĻŋ āĻ¯ā§ āĻāĻŽāĻžāĻĻā§āĻ° āĻā§āĻŦāĻ˛ āĻāĻāĻāĻŋāĻ āĻāĻā§)āĨ¤
āĻĻāĻžāĻ°ā§āĻļāĻ¨āĻŋāĻ āĻĄāĻŋāĻā§āĻ°ā§āĻļāĻ¨ChatMessageUI āĻā§āĻ˛āĻžāĻ¸ āĻāĻŦāĻ ChatRestApi.getLast āĻāĻāĻ¯āĻŧ āĻĒāĻĻā§āĻ§āĻ¤āĻŋāĻ āĻ¤āĻžāĻ˛āĻŋāĻāĻž āĻĄā§āĻāĻž āĻāĻžāĻāĻĒ āĻŦā§āĻ¯āĻŦāĻšāĻžāĻ° āĻāĻ°ā§ āĻ¯āĻāĻ¨ āĻĒā§āĻ°āĻā§āĻ¤āĻĒāĻā§āĻˇā§ āĻāĻāĻŋ āĻāĻāĻāĻŋ āĻ
āĻ°ā§āĻĄāĻžāĻ° āĻāĻ°āĻž āĻ¸ā§āĻāĨ¤ āĻāĻāĻŋ JDK-āĻ¤ā§ āĻāĻžāĻ°āĻžāĻĒ, āĻ¤āĻžāĻ āĻāĻ¨ā§āĻāĻžāĻ°āĻĢā§āĻ¸ āĻ¸ā§āĻ¤āĻ°ā§ āĻāĻĒāĻžāĻĻāĻžāĻ¨āĻā§āĻ˛āĻŋāĻ° āĻā§āĻ°āĻŽ āĻā§āĻˇāĻŖāĻž āĻāĻ°āĻž (āĻ¸āĻāĻ¯ā§āĻāĻ¨ āĻāĻŦāĻ āĻ¸āĻ°āĻžāĻ¨ā§āĻ° āĻ¸āĻŽāĻ¯āĻŧ āĻā§āĻ°āĻŽ āĻ¸āĻāĻ°āĻā§āĻˇāĻŖ āĻāĻ°āĻž) āĻāĻžāĻ āĻāĻ°āĻŦā§ āĻ¨āĻžāĨ¤ āĻ¸ā§āĻ¤āĻ°āĻžāĻ āĻ
āĻ°ā§āĻĄāĻžāĻ° āĻāĻ°āĻž āĻ¸ā§āĻā§āĻ° āĻĒā§āĻ°āĻ¯āĻŧā§āĻāĻ¨ āĻšāĻ¯āĻŧ āĻāĻŽāĻ¨ āĻā§āĻˇā§āĻ¤ā§āĻ°ā§ āĻāĻāĻāĻŋ āĻ¤āĻžāĻ˛āĻŋāĻāĻž āĻŦā§āĻ¯āĻŦāĻšāĻžāĻ° āĻāĻ°āĻž āĻ¸āĻžāĻ§āĻžāĻ°āĻŖ āĻ
āĻā§āĻ¯āĻžāĻ¸ āĻšāĻ¯āĻŧā§ āĻāĻ ā§āĻā§ (āĻāĻāĻāĻŋ āĻ˛āĻŋāĻā§āĻāĻĄāĻšā§āĻ¯āĻžāĻļāĻ¸ā§āĻāĻ āĻ°āĻ¯āĻŧā§āĻā§, āĻ¤āĻŦā§ āĻāĻāĻŋ āĻāĻāĻāĻŋ āĻāĻ¨ā§āĻāĻžāĻ°āĻĢā§āĻ¸ āĻ¨āĻ¯āĻŧ)āĨ¤
āĻā§āĻ°ā§āĻ¤ā§āĻŦāĻĒā§āĻ°ā§āĻŖ āĻ¸ā§āĻŽāĻžāĻŦāĻĻā§āĻ§āĻ¤āĻž: āĻāĻŽāĻ°āĻž āĻ
āĻ¨ā§āĻŽāĻžāĻ¨ āĻāĻ°āĻŦ āĻ¯ā§ āĻāĻ¤ā§āĻ¤āĻ° āĻŦāĻž āĻ¸ā§āĻĨāĻžāĻ¨āĻžāĻ¨ā§āĻ¤āĻ°ā§āĻ° āĻā§āĻ¨ āĻĻā§āĻ°ā§āĻ āĻā§āĻāĻ¨ āĻ¨ā§āĻāĨ¤ āĻ
āĻ°ā§āĻĨāĻžā§, āĻ¤āĻžāĻ°āĻž āĻŦāĻŋāĻĻā§āĻ¯āĻŽāĻžāĻ¨, āĻāĻŋāĻ¨ā§āĻ¤ā§ āĻ¤āĻžāĻĻā§āĻ° āĻĻā§āĻ°ā§āĻā§āĻ¯ āĻ¤āĻŋāĻ¨āĻāĻŋ āĻŦāĻžāĻ°ā§āĻ¤āĻž āĻ
āĻ¤āĻŋāĻā§āĻ°āĻŽ āĻāĻ°ā§ āĻ¨āĻžāĨ¤ āĻŦāĻžāĻ°ā§āĻ¤āĻžāĻā§āĻ˛āĻŋāĻ° āĻ¸āĻŽā§āĻĒā§āĻ°ā§āĻŖ āĻā§āĻāĻ¨āĻāĻŋ āĻ
āĻŦāĻļā§āĻ¯āĻ āĻĢā§āĻ°āĻ¨ā§āĻāĻāĻ¨ā§āĻĄā§ āĻĒā§āĻ°ā§āĻ°āĻŖ āĻāĻ°āĻž āĻāĻāĻŋāĻ¤āĨ¤
āĻŦāĻžāĻšā§āĻ¯āĻŋāĻ āĻĒāĻ°āĻŋāĻˇā§āĻŦāĻžāĻā§āĻ˛āĻŋ āĻĨā§āĻā§ āĻĄā§āĻāĻž āĻā§āĻ°āĻšāĻŖ āĻāĻ°āĻ¤ā§ āĻ¨āĻŋāĻŽā§āĻ¨āĻ˛āĻŋāĻāĻŋāĻ¤ APIāĻā§āĻ˛āĻŋ āĻ°āĻ¯āĻŧā§āĻā§:
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>
}
āĻāĻāĻŋ āĻĻā§āĻāĻž āĻ¯āĻžāĻ¯āĻŧ āĻ¯ā§ āĻŦāĻšāĻŋāĻ°āĻžāĻāĻ¤ āĻĒāĻ°āĻŋāĻˇā§āĻŦāĻžāĻā§āĻ˛āĻŋ āĻĒā§āĻ°āĻžāĻĨāĻŽāĻŋāĻāĻāĻžāĻŦā§ āĻŦā§āĻ¯āĻžāĻ āĻĒā§āĻ°āĻā§āĻ°āĻŋāĻ¯āĻŧāĻžāĻāĻ°āĻŖā§āĻ° āĻāĻ¨ā§āĻ¯ āĻ¸āĻ°āĻŦāĻ°āĻžāĻš āĻāĻ°ā§ āĻāĻŦāĻ āĻāĻāĻ¯āĻŧ āĻ¸āĻāĻ¸ā§āĻāĻ°āĻŖā§: āĻ¸ā§āĻā§āĻ° āĻŽāĻžāĻ§ā§āĻ¯āĻŽā§ (āĻāĻĒāĻžāĻĻāĻžāĻ¨ā§āĻ° āĻā§āĻ°āĻŽ āĻ¸āĻāĻ°āĻā§āĻˇāĻŖ āĻ¨āĻž āĻāĻ°ā§, āĻ āĻ¨āĻ¨ā§āĻ¯ āĻā§ āĻ¸āĻš) āĻāĻŦāĻ āĻ¤āĻžāĻ˛āĻŋāĻāĻžāĻ° āĻŽāĻžāĻ§ā§āĻ¯āĻŽā§ (āĻ¸āĻĻā§āĻļ āĻšāĻ¤ā§ āĻĒāĻžāĻ°ā§ - āĻ āĻ°ā§āĻĄāĻžāĻ°āĻāĻŋ āĻ¸āĻāĻ°āĻā§āĻˇāĻŖ āĻāĻ°āĻž āĻšāĻ¯āĻŧ)āĨ¤
āĻ¸āĻšāĻ āĻŦāĻžāĻ¸ā§āĻ¤āĻŦāĻžāĻ¯āĻŧāĻ¨
āĻ¨āĻŋāĻˇā§āĻĒāĻžāĻĒ āĻŦāĻžāĻ¸ā§āĻ¤āĻŦāĻžāĻ¯āĻŧāĻ¨
āĻāĻŽāĻžāĻĻā§āĻ° 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-āĻāĻ° ForwardFrom āĻāĻŦāĻ replyTo āĻĢāĻŋāĻ˛ā§āĻĄāĻā§āĻ˛āĻŋ āĻāĻŽāĻ¨āĻāĻžāĻŦā§ āĻĒā§āĻ°āĻžāĻĒā§āĻ¤ āĻāĻ°āĻž āĻšāĻ¯āĻŧā§āĻā§ āĻ¯āĻžāĻ¤ā§ āĻ āĻĒā§āĻ°āĻ¯āĻŧā§āĻāĻ¨ā§āĻ¯āĻŧ āĻāĻ˛ā§āĻ° āĻĒā§āĻ°āĻ¯āĻŧā§āĻāĻ¨ āĻšāĻ¯āĻŧ āĻ¨āĻžāĨ¤ āĻāĻŋāĻ¨ā§āĻ¤ā§ āĻ¸ā§āĻā§āĻ˛āĻŋāĻā§ ChatMessageUI-āĻ¤ā§ āĻĒāĻ°āĻŋāĻŖāĻ¤ āĻāĻ°āĻ˛ā§ āĻ¤āĻž āĻĒā§āĻ¨āĻ°āĻžāĻŦā§āĻ¤ā§āĻ¤āĻŋ āĻāĻāĻŦā§, āĻ āĻ°ā§āĻĨāĻžā§ āĻāĻ˛ āĻāĻžāĻāĻ¨ā§āĻāĻžāĻ°āĻā§āĻ˛āĻŋ āĻāĻ˛ā§āĻ˛ā§āĻāĻ¯ā§āĻā§āĻ¯āĻāĻžāĻŦā§ āĻŦā§āĻĻā§āĻ§āĻŋ āĻĒā§āĻ¤ā§ āĻĒāĻžāĻ°ā§ā§ˇ āĻ¯ā§āĻŽāĻ¨āĻāĻŋ āĻāĻŽāĻ°āĻž āĻāĻā§ āĻāĻ˛ā§āĻ˛ā§āĻ āĻāĻ°ā§āĻāĻŋ, āĻāĻ¸ā§āĻ¨ āĻ§āĻ°ā§ āĻ¨āĻŋāĻ āĻ¯ā§ āĻāĻŽāĻžāĻĻā§āĻ° āĻ āĻ¨ā§āĻ āĻ¨ā§āĻ¸ā§āĻāĻŋāĻ āĻ¨ā§āĻ āĻāĻŦāĻ āĻā§āĻāĻ¨āĻāĻŋ āĻ¤āĻŋāĻ¨āĻāĻŋ āĻŦāĻžāĻ°ā§āĻ¤āĻžāĻ° āĻŽāĻ§ā§āĻ¯ā§ āĻ¸ā§āĻŽāĻžāĻŦāĻĻā§āĻ§āĨ¤
āĻĢāĻ˛āĻ¸ā§āĻŦāĻ°ā§āĻĒ, āĻāĻŽāĻ°āĻž āĻĒā§āĻ°āĻ¤āĻŋ āĻŦāĻžāĻ°ā§āĻ¤āĻžāĻ¯āĻŧ āĻŦāĻžāĻšā§āĻ¯āĻŋāĻ āĻĒāĻ°āĻŋāĻˇā§āĻŦāĻžāĻā§āĻ˛āĻŋāĻ¤ā§ āĻĻā§āĻ āĻĨā§āĻā§ āĻāĻ¯āĻŧāĻāĻŋ āĻāĻ˛ āĻāĻŦāĻ āĻŦāĻžāĻ°ā§āĻ¤āĻžāĻā§āĻ˛āĻŋāĻ° āĻ¸āĻŽā§āĻĒā§āĻ°ā§āĻŖ āĻĒā§āĻ¯āĻžāĻā§āĻā§āĻ° āĻāĻ¨ā§āĻ¯ āĻāĻāĻāĻŋ JPA āĻāĻ˛ āĻĒāĻžāĻŦāĨ¤ āĻŽā§āĻ āĻāĻ˛ā§āĻ° āĻ¸āĻāĻā§āĻ¯āĻž 2*N+1 āĻĨā§āĻā§ 6*N+1 āĻĒāĻ°ā§āĻ¯āĻ¨ā§āĻ¤ āĻĒāĻ°āĻŋāĻŦāĻ°ā§āĻ¤āĻŋāĻ¤ āĻšāĻŦā§āĨ¤ āĻŦāĻžāĻ¸ā§āĻ¤āĻŦ āĻāĻāĻ¨āĻŋāĻā§ āĻāĻāĻŋ āĻāĻ¤? āĻ§āĻ°āĻž āĻ¯āĻžāĻ āĻāĻāĻāĻŋ āĻĒā§āĻˇā§āĻ āĻž āĻ°ā§āĻ¨ā§āĻĄāĻžāĻ° āĻāĻ°āĻ¤ā§ 20āĻāĻŋ āĻŦāĻžāĻ°ā§āĻ¤āĻž āĻ˛āĻžāĻā§āĨ¤ āĻ¸ā§āĻā§āĻ˛āĻŋ āĻĒā§āĻ¤ā§, āĻāĻāĻŋ 4 āĻ¸ā§āĻā§āĻ¨ā§āĻĄ āĻĨā§āĻā§ 10 āĻ¸ā§āĻā§āĻ¨ā§āĻĄ āĻĒāĻ°ā§āĻ¯āĻ¨ā§āĻ¤ āĻ˛āĻžāĻāĻŦā§āĨ¤ āĻāĻ¯āĻŧāĻžāĻ¨āĻ! āĻāĻŽāĻŋ āĻāĻāĻŋ 500 ms āĻāĻ° āĻŽāĻ§ā§āĻ¯ā§ āĻ°āĻžāĻāĻ¤ā§ āĻāĻžāĻāĨ¤ āĻāĻŦāĻ āĻ¯ā§āĻšā§āĻ¤ā§ āĻ¤āĻžāĻ°āĻž āĻĢā§āĻ°āĻ¨ā§āĻāĻāĻ¨ā§āĻĄā§ āĻ¨āĻŋāĻ°ā§āĻŦāĻŋāĻā§āĻ¨ āĻ¸ā§āĻā§āĻ°āĻ˛āĻŋāĻ āĻāĻ°āĻžāĻ° āĻ¸ā§āĻŦāĻĒā§āĻ¨ āĻĻā§āĻā§āĻāĻŋāĻ˛, āĻ¤āĻžāĻ āĻāĻ āĻļā§āĻˇ āĻĒāĻ¯āĻŧā§āĻ¨ā§āĻā§āĻ° āĻāĻ¨ā§āĻ¯ āĻāĻ°ā§āĻŽāĻā§āĻˇāĻŽāĻ¤āĻž āĻĒā§āĻ°āĻ¯āĻŧā§āĻāĻ¨ā§āĻ¯āĻŧāĻ¤āĻž āĻĻā§āĻŦāĻŋāĻā§āĻŖ āĻāĻ°āĻž āĻ¯ā§āĻ¤ā§ āĻĒāĻžāĻ°ā§āĨ¤
āĻĒā§āĻļāĻžāĻĻāĻžāĻ°āĻ°āĻž:
- āĻā§āĻĄāĻāĻŋ āĻ¸āĻāĻā§āĻˇāĻŋāĻĒā§āĻ¤ āĻāĻŦāĻ āĻ¸ā§āĻŦ-āĻĄāĻā§āĻŽā§āĻ¨ā§āĻāĻŋāĻ (āĻāĻāĻāĻŋ āĻ¸āĻŽāĻ°ā§āĻĨāĻ¨ āĻĻāĻ˛ā§āĻ° āĻ¸ā§āĻŦāĻĒā§āĻ¨)āĨ¤
- āĻā§āĻĄāĻāĻŋ āĻ¸āĻšāĻ, āĻ¤āĻžāĻ āĻ¨āĻŋāĻā§āĻā§ āĻĒāĻžāĻ¯āĻŧā§ āĻā§āĻ˛āĻŋ āĻāĻ°āĻžāĻ° āĻĒā§āĻ°āĻžāĻ¯āĻŧ āĻā§āĻ¨ āĻ¸ā§āĻ¯ā§āĻ āĻ¨ā§āĻāĨ¤
- āĻŦā§āĻ¯āĻžāĻ āĻĒā§āĻ°āĻ¸ā§āĻ¸āĻŋāĻ āĻāĻŋāĻā§ āĻĒāĻ°āĻ āĻŽāĻ¤ āĻĻā§āĻāĻžāĻ¯āĻŧ āĻ¨āĻž āĻāĻŦāĻ āĻā§āĻŦāĻāĻžāĻŦā§ āĻ¯ā§āĻā§āĻ¤āĻŋāĻ¤ā§ āĻāĻāĻ¤ā§āĻ°āĻŋāĻ¤ āĻāĻ°āĻž āĻšāĻ¯āĻŧ.
- āĻ¯ā§āĻā§āĻ¤āĻŋ āĻĒāĻ°āĻŋāĻŦāĻ°ā§āĻ¤āĻ¨ āĻ¸āĻšāĻā§ āĻāĻ°āĻž āĻšāĻŦā§ āĻāĻŦāĻ āĻ¸ā§āĻĨāĻžāĻ¨ā§āĻ¯āĻŧ āĻšāĻŦā§.
āĻāĻŽ:
āĻā§āĻŦ āĻā§āĻ āĻĒā§āĻ¯āĻžāĻā§āĻā§āĻ° āĻāĻžāĻ°āĻŖā§ āĻāĻ¯āĻŧāĻā§āĻāĻ° āĻāĻ°ā§āĻŽāĻā§āĻˇāĻŽāĻ¤āĻžāĨ¤
āĻāĻ āĻĒāĻĻā§āĻ§āĻ¤āĻŋāĻāĻŋ āĻĒā§āĻ°āĻžāĻ¯āĻŧāĻļāĻ āĻ¸āĻžāĻ§āĻžāĻ°āĻŖ āĻĒāĻ°āĻŋāĻˇā§āĻŦāĻžāĻā§āĻ˛āĻŋāĻ¤ā§ āĻŦāĻž āĻĒā§āĻ°ā§āĻā§āĻāĻžāĻāĻĒāĻā§āĻ˛āĻŋāĻ¤ā§ āĻĻā§āĻāĻž āĻ¯āĻžāĻ¯āĻŧāĨ¤ āĻ¯āĻĻāĻŋ āĻĒāĻ°āĻŋāĻŦāĻ°ā§āĻ¤āĻ¨ āĻāĻ°āĻžāĻ° āĻāĻ¤āĻŋ āĻā§āĻ°ā§āĻ¤ā§āĻŦāĻĒā§āĻ°ā§āĻŖ āĻšāĻ¯āĻŧ, āĻ¤āĻŦā§ āĻāĻāĻŋ āĻ¸āĻŋāĻ¸ā§āĻā§āĻŽāĻā§ āĻāĻāĻŋāĻ˛ āĻāĻ°ā§ āĻ¤ā§āĻ˛āĻžāĻ° āĻĒāĻā§āĻˇā§ āĻā§āĻŦ āĻāĻŽāĻ āĻāĻĒāĻ¯ā§āĻā§āĻ¤āĨ¤ āĻāĻāĻ āĻ¸āĻŽāĻ¯āĻŧā§, āĻāĻŽāĻžāĻĻā§āĻ° āĻā§āĻŦ āĻ¸āĻžāĻ§āĻžāĻ°āĻŖ āĻĒāĻ°āĻŋāĻˇā§āĻŦāĻžāĻ° āĻāĻ¨ā§āĻ¯ āĻāĻ°ā§āĻŽāĻā§āĻˇāĻŽāĻ¤āĻž āĻāĻ¯āĻŧāĻžāĻ¨āĻ, āĻ¤āĻžāĻ āĻāĻ āĻĒāĻĻā§āĻ§āĻ¤āĻŋāĻ° āĻĒā§āĻ°āĻ¯āĻŧā§āĻā§āĻ° āĻ¸ā§āĻ¯ā§āĻ āĻā§āĻŦ āĻ¸āĻāĻā§āĻ°ā§āĻŖāĨ¤
āĻ¨āĻŋāĻˇā§āĻĒāĻžāĻĒ āĻ¸āĻŽāĻžāĻ¨ā§āĻ¤āĻ°āĻžāĻ˛ āĻĒā§āĻ°āĻā§āĻ°āĻŋāĻ¯āĻŧāĻžāĻāĻ°āĻŖ
āĻāĻĒāĻ¨āĻŋ āĻ¸āĻŽāĻžāĻ¨ā§āĻ¤āĻ°āĻžāĻ˛āĻāĻžāĻŦā§ āĻ¸āĻŽāĻ¸ā§āĻ¤ āĻŦāĻžāĻ°ā§āĻ¤āĻž āĻĒā§āĻ°āĻā§āĻ°āĻŋāĻ¯āĻŧāĻžāĻāĻ°āĻŖ āĻļā§āĻ°ā§ āĻāĻ°āĻ¤ā§ āĻĒāĻžāĻ°ā§āĻ¨ - āĻāĻāĻŋ āĻāĻĒāĻ¨āĻžāĻā§ āĻŦāĻžāĻ°ā§āĻ¤āĻžāĻā§āĻ˛āĻŋāĻ° āĻ¸āĻāĻā§āĻ¯āĻžāĻ° āĻāĻĒāĻ° āĻ¨āĻŋāĻ°ā§āĻāĻ° āĻāĻ°ā§ āĻ¸āĻŽāĻ¯āĻŧā§āĻ° āĻ°ā§āĻāĻŋāĻ āĻŦā§āĻĻā§āĻ§āĻŋ āĻĨā§āĻā§ āĻĒāĻ°āĻŋāĻ¤ā§āĻ°āĻžāĻŖ āĻĒā§āĻ¤ā§ āĻĻā§āĻ¯āĻŧāĨ¤ āĻāĻāĻŋ āĻāĻāĻāĻŋ āĻŦāĻŋāĻļā§āĻˇāĻāĻžāĻŦā§ āĻāĻžāĻ˛ āĻĒāĻĨ āĻ¨āĻ¯āĻŧ āĻāĻžāĻ°āĻŖ āĻāĻ° āĻĢāĻ˛ā§ āĻŦāĻšāĻŋāĻ°āĻžāĻāĻ¤ āĻĒāĻ°āĻŋāĻˇā§āĻŦāĻžāĻ° āĻāĻĒāĻ° āĻāĻāĻāĻŋ āĻŦāĻĄāĻŧ āĻĒāĻŋāĻ āĻ˛ā§āĻĄ āĻšāĻŦā§ā§ˇ
āĻ¸āĻŽāĻžāĻ¨ā§āĻ¤āĻ°āĻžāĻ˛ āĻĒā§āĻ°āĻā§āĻ°āĻŋāĻ¯āĻŧāĻžāĻāĻ°āĻŖ āĻŦāĻžāĻ¸ā§āĻ¤āĻŦāĻžāĻ¯āĻŧāĻ¨ āĻāĻ°āĻž āĻā§āĻŦāĻ āĻ¸āĻšāĻ:
override fun getLast(n: Int) =
messageRepository.findLast(n).parallelStream()
.map { it.toFrontModel() }
.collect(toList())
āĻ¸āĻŽāĻžāĻ¨ā§āĻ¤āĻ°āĻžāĻ˛ āĻŦāĻžāĻ°ā§āĻ¤āĻž āĻĒā§āĻ°āĻā§āĻ°āĻŋāĻ¯āĻŧāĻžāĻāĻ°āĻŖ āĻŦā§āĻ¯āĻŦāĻšāĻžāĻ° āĻāĻ°ā§, āĻāĻŽāĻ°āĻž āĻāĻĻāĻ°ā§āĻļāĻāĻžāĻŦā§ 300-700 ms āĻĒāĻžāĻ, āĻ¯āĻž āĻāĻāĻāĻŋ āĻ¨āĻŋāĻˇā§āĻĒāĻžāĻĒ āĻŦāĻžāĻ¸ā§āĻ¤āĻŦāĻžāĻ¯āĻŧāĻ¨ā§āĻ° āĻ¤ā§āĻ˛āĻ¨āĻžāĻ¯āĻŧ āĻ āĻ¨ā§āĻ āĻāĻžāĻ˛ā§, āĻāĻŋāĻ¨ā§āĻ¤ā§ āĻāĻāĻ¨āĻ āĻ¯āĻĨā§āĻˇā§āĻ āĻĻā§āĻ°ā§āĻ¤ āĻ¨āĻ¯āĻŧāĨ¤
āĻāĻ āĻĒāĻĻā§āĻ§āĻ¤āĻŋāĻ° āĻ¸āĻžāĻĨā§, userRepository āĻāĻŦāĻ fileRepository-āĻāĻ° āĻ āĻ¨ā§āĻ°ā§āĻ§āĻā§āĻ˛āĻŋ āĻ¸āĻŋāĻā§āĻā§āĻ°ā§āĻ¨āĻžāĻ¸āĻāĻžāĻŦā§ āĻāĻžāĻ°ā§āĻ¯āĻāĻ° āĻāĻ°āĻž āĻšāĻŦā§, āĻ¯āĻž āĻā§āĻŦ āĻāĻžāĻ°ā§āĻ¯āĻāĻ° āĻ¨āĻ¯āĻŧāĨ¤ āĻāĻāĻŋ āĻ āĻŋāĻ āĻāĻ°āĻžāĻ° āĻāĻ¨ā§āĻ¯, āĻāĻĒāĻ¨āĻžāĻā§ āĻāĻ˛ āĻ˛āĻāĻŋāĻ āĻ āĻ¨ā§āĻ āĻĒāĻ°āĻŋāĻŦāĻ°ā§āĻ¤āĻ¨ āĻāĻ°āĻ¤ā§ āĻšāĻŦā§āĨ¤ āĻāĻĻāĻžāĻšāĻ°āĻŖāĻ¸ā§āĻŦāĻ°ā§āĻĒ, CompletionStage āĻāĻ° āĻŽāĻžāĻ§ā§āĻ¯āĻŽā§ (āĻāĻ°āĻĢā§ Completable Future):
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()!!
āĻāĻāĻŋ āĻĻā§āĻāĻž āĻ¯āĻžāĻ¯āĻŧ āĻ¯ā§ āĻĒā§āĻ°āĻžāĻĨāĻŽāĻŋāĻāĻāĻžāĻŦā§ āĻ¸āĻšāĻ āĻŽā§āĻ¯āĻžāĻĒāĻŋāĻ āĻā§āĻĄ āĻāĻŽ āĻŦā§āĻ§āĻāĻŽā§āĻ¯ āĻšāĻ¯āĻŧā§āĻā§āĨ¤ āĻāĻ° āĻāĻžāĻ°āĻŖ āĻšāĻ˛ āĻ¯ā§ āĻĢāĻ˛āĻžāĻĢāĻ˛āĻā§āĻ˛āĻŋ āĻŦā§āĻ¯āĻŦāĻšāĻžāĻ° āĻāĻ°āĻž āĻšāĻ¯āĻŧ āĻ¸ā§āĻāĻžāĻ¨ āĻĨā§āĻā§ āĻāĻŽāĻžāĻĻā§āĻ° āĻŦāĻšāĻŋāĻ°āĻžāĻāĻ¤ āĻĒāĻ°āĻŋāĻˇā§āĻŦāĻžāĻā§āĻ˛āĻŋāĻ¤ā§ āĻāĻ˛āĻā§āĻ˛āĻŋāĻā§ āĻāĻ˛āĻžāĻĻāĻž āĻāĻ°āĻ¤ā§ āĻšāĻ¯āĻŧā§āĻāĻŋāĻ˛ā§ˇ āĻāĻāĻŋ āĻ¨āĻŋāĻā§āĻ āĻāĻžāĻ°āĻžāĻĒ āĻ¨āĻ¯āĻŧāĨ¤ āĻ¤āĻŦā§ āĻāĻ˛āĻā§āĻ˛āĻŋāĻā§ āĻāĻāĻ¤ā§āĻ°āĻŋāĻ¤ āĻāĻ°āĻž āĻā§āĻŦ āĻŽāĻžāĻ°ā§āĻāĻŋāĻ¤ āĻĻā§āĻāĻžāĻ¯āĻŧ āĻ¨āĻž āĻāĻŦāĻ āĻāĻāĻāĻŋ āĻ¸āĻžāĻ§āĻžāĻ°āĻŖ āĻĒā§āĻ°āĻ¤āĻŋāĻā§āĻ°āĻŋāĻ¯āĻŧāĻžāĻļā§āĻ˛ "āĻ¨ā§āĻĄāĻ˛" āĻāĻ° āĻŽāĻ¤ā§āĨ¤
āĻāĻĒāĻ¨āĻŋ coroutines āĻŦā§āĻ¯āĻŦāĻšāĻžāĻ° āĻāĻ°āĻ˛ā§, āĻ¸āĻŦāĻāĻŋāĻā§ āĻāĻ°ā§ āĻļāĻžāĻ˛ā§āĻ¨ āĻĻā§āĻāĻžāĻŦā§:
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 ms āĻĒāĻžāĻŦ, āĻ¯āĻž āĻāĻ¤āĻŋāĻŽāĻ§ā§āĻ¯ā§āĻ āĻāĻŽāĻžāĻĻā§āĻ° āĻĒā§āĻ°āĻ¤ā§āĻ¯āĻžāĻļāĻžāĻ° āĻāĻžāĻāĻžāĻāĻžāĻāĻŋāĨ¤
āĻĻā§āĻ°ā§āĻāĻžāĻā§āĻ¯āĻŦāĻļāĻ¤, āĻāĻ āĻ§āĻ°āĻ¨ā§āĻ° āĻāĻžāĻ˛ āĻ¸āĻŽāĻžāĻ¨ā§āĻ¤āĻ°āĻžāĻ˛āĻāĻ°āĻŖ āĻŦāĻŋāĻĻā§āĻ¯āĻŽāĻžāĻ¨ āĻ¨ā§āĻ, āĻāĻŦāĻ āĻĒā§āĻ°āĻĻāĻžāĻ¨ā§āĻ° āĻŽā§āĻ˛ā§āĻ¯ āĻŦā§āĻļ āĻ¨āĻŋāĻˇā§āĻ ā§āĻ°: āĻāĻāĻ āĻ¸āĻŽāĻ¯āĻŧā§ āĻļā§āĻ§ā§āĻŽāĻžāĻ¤ā§āĻ° āĻāĻ¯āĻŧā§āĻāĻāĻ¨ āĻŦā§āĻ¯āĻŦāĻšāĻžāĻ°āĻāĻžāĻ°ā§ āĻāĻžāĻ āĻāĻ°āĻžāĻ° āĻ¸āĻžāĻĨā§, āĻ āĻ¨ā§āĻ°ā§āĻ§ā§āĻ° āĻāĻāĻāĻŋ āĻŦā§āĻ¯āĻžāĻ°ā§āĻ āĻĒāĻ°āĻŋāĻˇā§āĻŦāĻžāĻā§āĻ˛āĻŋāĻ¤ā§ āĻĒāĻĄāĻŧāĻŦā§, āĻ¯āĻž āĻ¯āĻžāĻāĻšā§āĻ āĻ¸āĻŽāĻžāĻ¨ā§āĻ¤āĻ°āĻžāĻ˛āĻāĻžāĻŦā§ āĻĒā§āĻ°āĻā§āĻ°āĻŋāĻ¯āĻŧāĻž āĻāĻ°āĻž āĻšāĻŦā§ āĻ¨āĻž, āĻ¤āĻžāĻ āĻāĻŽāĻ°āĻž āĻāĻŽāĻžāĻĻā§āĻ° āĻĻā§āĻāĻāĻāĻ¨āĻ 4 āĻ¸ā§āĻā§āĻ¨ā§āĻĄā§ āĻĢāĻŋāĻ°ā§ āĻāĻ¸āĻŦā§āĨ¤
āĻāĻ āĻ§āĻ°āĻ¨ā§āĻ° āĻāĻāĻāĻŋ āĻĒāĻ°āĻŋāĻˇā§āĻŦāĻž āĻŦā§āĻ¯āĻŦāĻšāĻžāĻ° āĻāĻ°āĻžāĻ° āĻ¸āĻŽāĻ¯āĻŧ āĻāĻŽāĻžāĻ° āĻĢāĻ˛āĻžāĻĢāĻ˛ āĻšāĻ˛ 1300āĻāĻŋ āĻŦāĻžāĻ°ā§āĻ¤āĻž āĻĒā§āĻ°āĻā§āĻ°āĻŋāĻ¯āĻŧāĻžāĻāĻ°āĻŖā§āĻ° āĻāĻ¨ā§āĻ¯ 1700-20 msāĨ¤ āĻāĻāĻŋ āĻĒā§āĻ°āĻĨāĻŽ āĻŦāĻžāĻ¸ā§āĻ¤āĻŦāĻžāĻ¯āĻŧāĻ¨ā§āĻ° āĻ¤ā§āĻ˛āĻ¨āĻžāĻ¯āĻŧ āĻĻā§āĻ°ā§āĻ¤, āĻāĻŋāĻ¨ā§āĻ¤ā§ āĻāĻāĻ¨āĻ āĻ¸āĻŽāĻ¸ā§āĻ¯āĻžāĻ° āĻ¸āĻŽāĻžāĻ§āĻžāĻ¨ āĻāĻ°ā§ āĻ¨āĻžāĨ¤
āĻ¸āĻŽāĻžāĻ¨ā§āĻ¤āĻ°āĻžāĻ˛ āĻĒā§āĻ°āĻļā§āĻ¨ā§āĻ° āĻŦāĻŋāĻāĻ˛ā§āĻĒ āĻŦā§āĻ¯āĻŦāĻšāĻžāĻ°āĻ¯āĻĻāĻŋ āĻ¤ā§āĻ¤ā§āĻ¯āĻŧ āĻĒāĻā§āĻˇā§āĻ° āĻĒāĻ°āĻŋāĻˇā§āĻŦāĻžāĻā§āĻ˛āĻŋ āĻŦā§āĻ¯āĻžāĻ āĻĒā§āĻ°āĻā§āĻ°āĻŋāĻ¯āĻŧāĻžāĻāĻ°āĻŖ āĻĒā§āĻ°āĻĻāĻžāĻ¨ āĻ¨āĻž āĻāĻ°ā§? āĻāĻĻāĻžāĻšāĻ°āĻŖāĻ¸ā§āĻŦāĻ°ā§āĻĒ, āĻāĻĒāĻ¨āĻŋ āĻāĻ¨ā§āĻāĻžāĻ°āĻĢā§āĻ¸ āĻĒāĻĻā§āĻ§āĻ¤āĻŋāĻ° āĻāĻŋāĻ¤āĻ°ā§ āĻŦā§āĻ¯āĻžāĻ āĻĒā§āĻ°āĻā§āĻ°āĻŋāĻ¯āĻŧāĻžāĻāĻ°āĻŖ āĻŦāĻžāĻ¸ā§āĻ¤āĻŦāĻžāĻ¯āĻŧāĻ¨ā§āĻ° āĻ āĻāĻžāĻŦ āĻ˛ā§āĻāĻžāĻ¤ā§ āĻĒāĻžāĻ°ā§āĻ¨:
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())
}
āĻāĻĒāĻ¨āĻŋ āĻ¯āĻĻāĻŋ āĻāĻŦāĻŋāĻˇā§āĻ¯āĻ¤ā§āĻ° āĻ¸āĻāĻ¸ā§āĻāĻ°āĻŖāĻā§āĻ˛āĻŋāĻ¤ā§ āĻŦā§āĻ¯āĻžāĻ āĻĒā§āĻ°āĻā§āĻ°āĻŋāĻ¯āĻŧāĻžāĻāĻ°āĻŖ āĻĻā§āĻāĻ¤ā§ āĻāĻļāĻž āĻāĻ°ā§āĻ¨ āĻ¤āĻŦā§ āĻāĻāĻŋ āĻŦā§āĻāĻž āĻ¯āĻžāĻ¯āĻŧāĨ¤
āĻĒā§āĻļāĻžāĻĻāĻžāĻ°āĻ°āĻž:
- āĻ¸āĻšāĻā§ āĻŦāĻžāĻ°ā§āĻ¤āĻž-āĻāĻŋāĻ¤ā§āĻ¤āĻŋāĻ āĻ¸āĻŽāĻžāĻ¨ā§āĻ¤āĻ°āĻžāĻ˛ āĻĒā§āĻ°āĻā§āĻ°āĻŋāĻ¯āĻŧāĻžāĻāĻ°āĻŖ āĻŦāĻžāĻ¸ā§āĻ¤āĻŦāĻžāĻ¯āĻŧāĻ¨.
- āĻāĻžāĻ˛ āĻŽāĻžāĻĒāĻ¯ā§āĻā§āĻ¯āĻ¤āĻž.
āĻāĻ¨āĻ¸:
- āĻ¸āĻŽāĻžāĻ¨ā§āĻ¤āĻ°āĻžāĻ˛āĻāĻžāĻŦā§ āĻŦāĻŋāĻāĻŋāĻ¨ā§āĻ¨ āĻĒāĻ°āĻŋāĻˇā§āĻŦāĻžāĻ° āĻ āĻ¨ā§āĻ°ā§āĻ§āĻā§āĻ˛āĻŋ āĻĒā§āĻ°āĻā§āĻ°āĻŋāĻ¯āĻŧāĻž āĻāĻ°āĻžāĻ° āĻ¸āĻŽāĻ¯āĻŧ āĻāĻ° āĻĒā§āĻ°āĻā§āĻ°āĻŋāĻ¯āĻŧāĻžāĻāĻ°āĻŖ āĻĨā§āĻā§ āĻĄā§āĻāĻž āĻ āĻ§āĻŋāĻā§āĻ°āĻšāĻŖāĻā§ āĻāĻ˛āĻžāĻĻāĻž āĻāĻ°āĻžāĻ° āĻĒā§āĻ°āĻ¯āĻŧā§āĻāĻ¨āĨ¤
- āĻ¤ā§āĻ¤ā§āĻ¯āĻŧ āĻĒāĻā§āĻˇā§āĻ° āĻĒāĻ°āĻŋāĻˇā§āĻŦāĻžāĻā§āĻ˛āĻŋāĻ¤ā§ āĻŦāĻ°ā§āĻ§āĻŋāĻ¤ āĻ˛ā§āĻĄāĨ¤
āĻāĻāĻž āĻĻā§āĻāĻž āĻ¯āĻžāĻ¯āĻŧ āĻ¯ā§ āĻĒā§āĻ°āĻ¯ā§āĻā§āĻ¯āĻ¤āĻžāĻ° āĻ¸ā§āĻ¯ā§āĻ āĻĒā§āĻ°āĻžāĻ¯āĻŧ āĻ¨āĻŋāĻ°ā§āĻŦā§āĻ§ āĻĒāĻĻā§āĻ§āĻ¤āĻŋāĻ° āĻŽāĻ¤ā§āĻāĨ¤ āĻāĻĒāĻ¨āĻŋ āĻ¯āĻĻāĻŋ āĻ āĻ¨ā§āĻ¯āĻĻā§āĻ° āĻ¨āĻŋāĻ°ā§āĻĻāĻ¯āĻŧ āĻļā§āĻˇāĻŖā§āĻ° āĻāĻžāĻ°āĻŖā§ āĻāĻĒāĻ¨āĻžāĻ° āĻĒāĻ°āĻŋāĻˇā§āĻŦāĻžāĻ° āĻāĻ°ā§āĻŽāĻā§āĻˇāĻŽāĻ¤āĻž āĻāĻ¯āĻŧā§āĻāĻā§āĻŖ āĻŦāĻžāĻĄāĻŧāĻžāĻ¤ā§ āĻāĻžāĻ¨ āĻ¤āĻŦā§ āĻ¸āĻŽāĻžāĻ¨ā§āĻ¤āĻ°āĻžāĻ˛ āĻ āĻ¨ā§āĻ°ā§āĻ§ āĻĒāĻĻā§āĻ§āĻ¤āĻŋ āĻŦā§āĻ¯āĻŦāĻšāĻžāĻ° āĻāĻ°āĻž āĻŦā§āĻ§āĻāĻŽā§āĻ¯āĨ¤ āĻāĻŽāĻžāĻĻā§āĻ° āĻāĻĻāĻžāĻšāĻ°āĻŖā§, āĻāĻ°ā§āĻŽāĻā§āĻˇāĻŽāĻ¤āĻž 2,5 āĻā§āĻŖ āĻŦā§āĻĄāĻŧā§āĻā§, āĻ¤āĻŦā§ āĻāĻāĻŋ āĻ¸ā§āĻĒāĻˇā§āĻāĻ¤āĻ āĻ¯āĻĨā§āĻˇā§āĻ āĻ¨āĻ¯āĻŧāĨ¤
āĻā§āĻ¯āĻžāĻļāĻŋāĻ
āĻāĻĒāĻ¨āĻŋ āĻŦāĻžāĻšā§āĻ¯āĻŋāĻ āĻĒāĻ°āĻŋāĻˇā§āĻŦāĻžāĻā§āĻ˛āĻŋāĻ° āĻāĻ¨ā§āĻ¯ JPA-āĻāĻ° āĻ¸ā§āĻĒāĻŋāĻ°āĻŋāĻā§ āĻā§āĻ¯āĻžāĻļāĻŋāĻ āĻāĻ°āĻ¤ā§ āĻĒāĻžāĻ°ā§āĻ¨, āĻ āĻ°ā§āĻĨāĻžā§, āĻĒā§āĻ°āĻžāĻĒā§āĻ¤ āĻŦāĻ¸ā§āĻ¤ā§āĻā§āĻ˛āĻŋāĻā§ āĻāĻāĻāĻŋ āĻ¸ā§āĻļāĻ¨ā§āĻ° āĻŽāĻ§ā§āĻ¯ā§ āĻ¸āĻāĻ°āĻā§āĻˇāĻŖ āĻāĻ°ā§āĻ¨ āĻ¯āĻžāĻ¤ā§ āĻ¸ā§āĻā§āĻ˛āĻŋ āĻāĻŦāĻžāĻ° āĻ¨āĻž āĻĒāĻžāĻāĻ¯āĻŧāĻž āĻ¯āĻžāĻ¯āĻŧ (āĻŦā§āĻ¯āĻžāĻ āĻĒā§āĻ°āĻā§āĻ°āĻŋāĻ¯āĻŧāĻžāĻāĻ°āĻŖā§āĻ° āĻ¸āĻŽāĻ¯āĻŧ āĻ¸āĻš)āĨ¤ āĻāĻĒāĻ¨āĻŋ āĻ¨āĻŋāĻā§ āĻāĻ āĻ§āĻ°āĻ¨ā§āĻ° āĻā§āĻ¯āĻžāĻļā§ āĻ¤ā§āĻ°āĻŋ āĻāĻ°āĻ¤ā§ āĻĒāĻžāĻ°ā§āĻ¨, āĻāĻĒāĻ¨āĻŋ āĻ¸ā§āĻĒā§āĻ°āĻŋāĻāĻā§ āĻāĻ° @Cacheable āĻĻāĻŋāĻ¯āĻŧā§ āĻŦā§āĻ¯āĻŦāĻšāĻžāĻ° āĻāĻ°āĻ¤ā§ āĻĒāĻžāĻ°ā§āĻ¨, āĻāĻāĻžāĻĄāĻŧāĻžāĻ āĻāĻĒāĻ¨āĻŋ āĻ¸āĻŦāĻ¸āĻŽāĻ¯āĻŧ EhCache-āĻāĻ° āĻŽāĻ¤ā§ āĻ¤ā§āĻ°āĻŋ āĻā§āĻ¯āĻžāĻļā§ āĻŽā§āĻ¯āĻžāĻ¨ā§āĻ¯āĻŧāĻžāĻ˛āĻŋ āĻŦā§āĻ¯āĻŦāĻšāĻžāĻ° āĻāĻ°āĻ¤ā§ āĻĒāĻžāĻ°ā§āĻ¨āĨ¤
āĻāĻāĻāĻŋ āĻ¸āĻžāĻ§āĻžāĻ°āĻŖ āĻ¸āĻŽāĻ¸ā§āĻ¯āĻž āĻš'āĻ˛ āĻā§āĻ¯āĻžāĻļā§āĻā§āĻ˛āĻŋ āĻā§āĻŦāĻ˛ āĻ¤āĻāĻ¨āĻ āĻāĻžāĻ°ā§āĻ¯āĻāĻ° āĻ¯āĻĻāĻŋ āĻ¤āĻžāĻĻā§āĻ° āĻšāĻŋāĻ āĻĨāĻžāĻā§āĨ¤ āĻāĻŽāĻžāĻĻā§āĻ° āĻā§āĻˇā§āĻ¤ā§āĻ°ā§, āĻ˛ā§āĻāĻ āĻā§āĻˇā§āĻ¤ā§āĻ°ā§āĻ° āĻšāĻŋāĻ āĻā§āĻŦ āĻ¸āĻŽā§āĻāĻŦāĻ¤ (āĻāĻ¸ā§āĻ¨, 50%) āĻāĻŋāĻ¨ā§āĻ¤ā§ āĻĢāĻžāĻāĻ˛āĻā§āĻ˛āĻŋāĻ¤ā§ āĻā§āĻ¨āĻ āĻšāĻŋāĻ āĻšāĻŦā§ āĻ¨āĻžāĨ¤ āĻāĻ āĻĒāĻĻā§āĻ§āĻ¤āĻŋāĻ° āĻāĻŋāĻā§ āĻāĻ¨ā§āĻ¨āĻ¤āĻŋ āĻšāĻŦā§, āĻāĻŋāĻ¨ā§āĻ¤ā§ āĻāĻāĻŋ āĻāĻ°ā§āĻŽāĻā§āĻˇāĻŽāĻ¤āĻžāĻā§ āĻāĻŽā§āĻ˛ āĻĒāĻ°āĻŋāĻŦāĻ°ā§āĻ¤āĻ¨ āĻāĻ°āĻŦā§ āĻ¨āĻž (āĻāĻŦāĻ āĻāĻŽāĻžāĻĻā§āĻ° āĻāĻāĻāĻŋ āĻ āĻā§āĻ°āĻāĻ¤āĻŋ āĻĒā§āĻ°āĻ¯āĻŧā§āĻāĻ¨)āĨ¤
āĻāĻ¨ā§āĻāĻžāĻ°āĻ¸ā§āĻ¸āĻ¨ (āĻĻā§āĻ°ā§āĻ) āĻā§āĻ¯āĻžāĻļā§ āĻāĻāĻŋāĻ˛ āĻ āĻŦā§āĻ§āĻāĻ°āĻŖ āĻ¯ā§āĻā§āĻ¤āĻŋ āĻĒā§āĻ°āĻ¯āĻŧā§āĻāĻ¨āĨ¤ āĻ¸āĻžāĻ§āĻžāĻ°āĻŖāĻāĻžāĻŦā§, āĻāĻĒāĻ¨āĻŋ āĻ¯āĻ¤ āĻĒāĻ°ā§ āĻāĻ¨ā§āĻāĻžāĻ°āĻ¸ā§āĻļāĻ¨ āĻā§āĻ¯āĻžāĻļā§ āĻŦā§āĻ¯āĻŦāĻšāĻžāĻ° āĻāĻ°ā§ āĻĒāĻžāĻ°āĻĢāĻ°āĻŽā§āĻ¯āĻžāĻ¨ā§āĻ¸ āĻ¸āĻŽāĻ¸ā§āĻ¯āĻž āĻ¸āĻŽāĻžāĻ§āĻžāĻ¨ā§ āĻ¨āĻžāĻŽāĻŦā§āĻ¨, āĻ¤āĻ¤āĻ āĻāĻžāĻ˛ā§āĨ¤
āĻĒā§āĻļāĻžāĻĻāĻžāĻ°āĻ°āĻž:
- āĻā§āĻĄ āĻĒāĻ°āĻŋāĻŦāĻ°ā§āĻ¤āĻ¨ āĻ¨āĻž āĻāĻ°ā§ āĻā§āĻ¯āĻžāĻļāĻŋāĻ āĻĒā§āĻ°āĻ¯āĻŧā§āĻ āĻāĻ°ā§āĻ¨āĨ¤
- āĻāĻ¤ā§āĻĒāĻžāĻĻāĻ¨āĻļā§āĻ˛āĻ¤āĻž āĻāĻ¯āĻŧā§āĻāĻŦāĻžāĻ° āĻŦā§āĻĻā§āĻ§āĻŋ āĻĒā§āĻ¯āĻŧā§āĻā§ (āĻāĻŋāĻā§ āĻā§āĻˇā§āĻ¤ā§āĻ°ā§)āĨ¤
āĻāĻ¨āĻ¸:
- āĻā§āĻ˛āĻāĻžāĻŦā§ āĻŦā§āĻ¯āĻŦāĻšāĻžāĻ° āĻāĻ°āĻž āĻšāĻ˛ā§ āĻāĻ°ā§āĻŽāĻā§āĻˇāĻŽāĻ¤āĻž āĻšā§āĻ°āĻžāĻ¸ā§āĻ° āĻ¸āĻŽā§āĻāĻžāĻŦāĻ¨āĻžāĨ¤
- āĻŦāĻĄāĻŧ āĻŽā§āĻŽāĻ°āĻŋ āĻāĻāĻžāĻ°āĻšā§āĻĄ, āĻŦāĻŋāĻļā§āĻˇ āĻāĻ°ā§ āĻĻā§āĻ°ā§āĻ āĻā§āĻ¯āĻžāĻļā§ āĻ¸āĻšāĨ¤
- āĻāĻāĻŋāĻ˛ āĻ āĻŦā§āĻ§āĻ¤āĻž, āĻ¤ā§āĻ°ā§āĻāĻŋ āĻ¯āĻž āĻ°āĻžāĻ¨āĻāĻžāĻāĻŽā§ āĻšāĻžāĻ°ā§āĻĄ-āĻā§-āĻ°āĻŋāĻĒā§āĻ°ā§āĻĄāĻŋāĻāĻ¸ āĻ¸āĻŽāĻ¸ā§āĻ¯āĻžāĻ° āĻĻāĻŋāĻā§ āĻĒāĻ°āĻŋāĻāĻžāĻ˛āĻŋāĻ¤ āĻāĻ°āĻŦā§āĨ¤
āĻā§āĻŦ āĻĒā§āĻ°āĻžāĻ¯āĻŧāĻ, āĻā§āĻ¯āĻžāĻļā§ āĻļā§āĻ§ā§āĻŽāĻžāĻ¤ā§āĻ° āĻ¨āĻāĻļāĻž āĻ¸āĻŽāĻ¸ā§āĻ¯āĻž āĻĻā§āĻ°ā§āĻ¤ āĻĒā§āĻ¯āĻžāĻ āĻāĻĒ āĻāĻ°āĻ¤ā§ āĻŦā§āĻ¯āĻŦāĻšāĻžāĻ° āĻāĻ°āĻž āĻšāĻ¯āĻŧ. āĻāĻ° āĻ āĻ°ā§āĻĨ āĻāĻ āĻ¨āĻ¯āĻŧ āĻ¯ā§ āĻ¤āĻžāĻĻā§āĻ° āĻŦā§āĻ¯āĻŦāĻšāĻžāĻ° āĻāĻ°āĻž āĻāĻāĻŋāĻ¤ āĻ¨āĻ¯āĻŧāĨ¤ āĻ¯āĻžāĻāĻšā§āĻ, āĻāĻĒāĻ¨āĻžāĻ° āĻ¸āĻ°ā§āĻŦāĻĻāĻž āĻ¤āĻžāĻĻā§āĻ° āĻ¸āĻžāĻĨā§ āĻ¸āĻžāĻŦāĻ§āĻžāĻ¨āĻ¤āĻžāĻ° āĻ¸āĻžāĻĨā§ āĻāĻāĻ°āĻŖ āĻāĻ°āĻž āĻāĻāĻŋāĻ¤ āĻāĻŦāĻ āĻĒā§āĻ°āĻĨāĻŽā§ āĻĢāĻ˛āĻžāĻĢāĻ˛ā§āĻ° āĻāĻžāĻ°ā§āĻ¯āĻāĻžāĻ°āĻŋāĻ¤āĻž āĻ˛āĻžāĻā§āĻ° āĻŽā§āĻ˛ā§āĻ¯āĻžāĻ¯āĻŧāĻ¨ āĻāĻ°āĻž āĻāĻāĻŋāĻ¤ āĻāĻŦāĻ āĻļā§āĻ§ā§āĻŽāĻžāĻ¤ā§āĻ° āĻ¤āĻžāĻ°āĻĒāĻ° āĻāĻāĻāĻŋ āĻ¸āĻŋāĻĻā§āĻ§āĻžāĻ¨ā§āĻ¤ āĻ¨ā§āĻāĻ¯āĻŧāĻž āĻāĻāĻŋāĻ¤āĨ¤
āĻāĻŽāĻžāĻĻā§āĻ° āĻāĻĻāĻžāĻšāĻ°āĻŖā§, āĻā§āĻ¯āĻžāĻļā§ āĻĒā§āĻ°āĻžāĻ¯āĻŧ 25% āĻāĻžāĻ°ā§āĻ¯āĻā§āĻˇāĻŽāĻ¤āĻž āĻŦā§āĻĻā§āĻ§āĻŋ āĻĒā§āĻ°āĻĻāĻžāĻ¨ āĻāĻ°āĻŦā§āĨ¤ āĻāĻāĻ āĻ¸āĻŽāĻ¯āĻŧā§, āĻā§āĻ¯āĻžāĻļā§āĻā§āĻ˛āĻŋāĻ° āĻ āĻ¨ā§āĻ āĻ āĻ¸ā§āĻŦāĻŋāĻ§āĻž āĻ°āĻ¯āĻŧā§āĻā§, āĻ¤āĻžāĻ āĻāĻŽāĻŋ āĻ¸ā§āĻā§āĻ˛āĻŋ āĻāĻāĻžāĻ¨ā§ āĻŦā§āĻ¯āĻŦāĻšāĻžāĻ° āĻāĻ°āĻŦ āĻ¨āĻžāĨ¤
āĻĢāĻ˛āĻžāĻĢāĻ˛
āĻ¸ā§āĻ¤āĻ°āĻžāĻ, āĻāĻŽāĻ°āĻž āĻŦā§āĻ¯āĻžāĻ āĻĒā§āĻ°āĻ¸ā§āĻ¸āĻŋāĻ āĻŦā§āĻ¯āĻŦāĻšāĻžāĻ° āĻāĻ°ā§ āĻāĻŽāĻ¨ āĻāĻāĻāĻŋ āĻĒāĻ°āĻŋāĻˇā§āĻŦāĻžāĻ° āĻ¨āĻŋāĻˇā§āĻĒāĻžāĻĒ āĻŦāĻžāĻ¸ā§āĻ¤āĻŦāĻžāĻ¯āĻŧāĻ¨ā§āĻ° āĻĻāĻŋāĻā§ āĻ¤āĻžāĻāĻŋāĻ¯āĻŧā§āĻāĻŋ āĻāĻŦāĻ āĻāĻāĻŋāĻā§ āĻāĻ¤āĻŋ āĻŦāĻžāĻĄāĻŧāĻžāĻ¨ā§āĻ° āĻāĻŋāĻā§ āĻ¸āĻšāĻ āĻāĻĒāĻžāĻ¯āĻŧāĨ¤
āĻāĻ āĻ¸āĻŽāĻ¸ā§āĻ¤ āĻĒāĻĻā§āĻ§āĻ¤āĻŋāĻ° āĻĒā§āĻ°āĻ§āĻžāĻ¨ āĻ¸ā§āĻŦāĻŋāĻ§āĻž āĻšāĻ˛ āĻ¸āĻ°āĻ˛āĻ¤āĻž, āĻ¯āĻž āĻĨā§āĻā§ āĻ āĻ¨ā§āĻ āĻāĻ¨āĻ¨ā§āĻĻāĻĻāĻžāĻ¯āĻŧāĻ āĻĒāĻ°āĻŋāĻŖāĻ¤āĻŋ āĻ°āĻ¯āĻŧā§āĻā§āĨ¤
āĻāĻ āĻĒāĻĻā§āĻ§āĻ¤āĻŋāĻā§āĻ˛āĻŋāĻ° āĻāĻāĻāĻŋ āĻ¸āĻžāĻ§āĻžāĻ°āĻŖ āĻ¸āĻŽāĻ¸ā§āĻ¯āĻž āĻšāĻ˛ āĻĻā§āĻ°ā§āĻŦāĻ˛ āĻāĻ°ā§āĻŽāĻā§āĻˇāĻŽāĻ¤āĻž, āĻĒā§āĻ°āĻžāĻĨāĻŽāĻŋāĻāĻāĻžāĻŦā§ āĻĒā§āĻ¯āĻžāĻā§āĻā§āĻ° āĻāĻāĻžāĻ°ā§āĻ° āĻāĻžāĻ°āĻŖā§āĨ¤ āĻ āĻ¤āĻāĻŦ, āĻ¯āĻĻāĻŋ āĻāĻ āĻ¸āĻŽāĻžāĻ§āĻžāĻ¨āĻā§āĻ˛āĻŋ āĻāĻĒāĻ¨āĻžāĻ° āĻāĻĒāĻ¯ā§āĻā§āĻ¤ āĻ¨āĻž āĻšāĻ¯āĻŧ, āĻ¤āĻŦā§ āĻāĻāĻŋ āĻāĻ°āĻ āĻ°ā§āĻ¯āĻžāĻĄāĻŋāĻāĻžāĻ˛ āĻĒāĻĻā§āĻ§āĻ¤āĻŋ āĻŦāĻŋāĻŦā§āĻāĻ¨āĻž āĻāĻ°āĻž āĻŽā§āĻ˛ā§āĻ¯āĻŦāĻžāĻ¨āĨ¤
āĻĻā§āĻāĻŋ āĻĒā§āĻ°āĻ§āĻžāĻ¨ āĻĻāĻŋāĻ āĻ°āĻ¯āĻŧā§āĻā§ āĻ¯ā§āĻāĻžāĻ¨ā§ āĻāĻĒāĻ¨āĻŋ āĻ¸āĻŽāĻžāĻ§āĻžāĻ¨āĻā§āĻ˛āĻŋ āĻ¸āĻ¨ā§āĻ§āĻžāĻ¨ āĻāĻ°āĻ¤ā§ āĻĒāĻžāĻ°ā§āĻ¨:
- āĻĄā§āĻāĻž āĻ¸āĻš āĻ ā§āĻ¯āĻžāĻ¸āĻŋāĻā§āĻā§āĻ°ā§āĻ¨āĻžāĻ¸ āĻāĻžāĻ (āĻāĻāĻāĻŋ āĻĒā§āĻ¯āĻžāĻ°āĻžāĻĄāĻžāĻāĻŽ āĻĒāĻ°āĻŋāĻŦāĻ°ā§āĻ¤āĻ¨ā§āĻ° āĻĒā§āĻ°āĻ¯āĻŧā§āĻāĻ¨, āĻ¤āĻžāĻ āĻāĻ āĻ¨āĻŋāĻŦāĻ¨ā§āĻ§ā§ āĻāĻ˛ā§āĻāĻ¨āĻž āĻāĻ°āĻž āĻšāĻ¯āĻŧāĻ¨āĻŋ);
- āĻ¸āĻŋāĻā§āĻā§āĻ°ā§āĻ¨āĻžāĻ¸ āĻĒā§āĻ°āĻā§āĻ°āĻŋāĻ¯āĻŧāĻžāĻāĻ°āĻŖ āĻŦāĻāĻžāĻ¯āĻŧ āĻ°āĻžāĻāĻžāĻ° āĻ¸āĻŽāĻ¯āĻŧ āĻŦā§āĻ¯āĻžāĻā§āĻ° āĻĒāĻ°āĻŋāĻŦāĻ°ā§āĻ§āĻ¨āĨ¤
āĻŦā§āĻ¯āĻžāĻ āĻŦāĻ°ā§āĻ§āĻŋāĻ¤ āĻāĻ°āĻž āĻŦāĻžāĻšā§āĻ¯āĻŋāĻ āĻāĻ˛ā§āĻ° āĻ¸āĻāĻā§āĻ¯āĻž āĻ
āĻ¨ā§āĻ āĻāĻŽāĻŋāĻ¯āĻŧā§ āĻĻā§āĻŦā§ āĻāĻŦāĻ āĻāĻāĻ āĻ¸āĻžāĻĨā§ āĻā§āĻĄāĻāĻŋ āĻ¸āĻŋāĻā§āĻā§āĻ°ā§āĻ¨āĻžāĻ¸ āĻ°āĻžāĻāĻŦā§āĨ¤ āĻ¨āĻŋāĻŦāĻ¨ā§āĻ§ā§āĻ° āĻĒāĻ°āĻŦāĻ°ā§āĻ¤ā§ āĻ
āĻāĻļ āĻāĻ āĻŦāĻŋāĻˇāĻ¯āĻŧā§ āĻ¨āĻŋāĻŦā§āĻĻāĻŋāĻ¤ āĻāĻ°āĻž āĻšāĻŦā§.
āĻāĻ¤ā§āĻ¸: www.habr.com