ΠŸΡ€Π΅Ρ…Π²ΡŠΡ€Π»ΡΠ½Π΅ Π½Π° Π±Π΅ΠΊΠ΅Π½Π΄Π° Π½Π° PHP към ΡˆΠΈΠ½Π°Ρ‚Π° Π·Π° ΠΏΠΎΡ‚ΠΎΡ†ΠΈ Π½Π° Redis ΠΈ ΠΈΠ·Π±ΠΎΡ€ Π½Π° нСзависима ΠΎΡ‚ Ρ€Π°ΠΌΠΊΠ°Ρ‚Π° Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ°

ΠŸΡ€Π΅Ρ…Π²ΡŠΡ€Π»ΡΠ½Π΅ Π½Π° Π±Π΅ΠΊΠ΅Π½Π΄Π° Π½Π° PHP към ΡˆΠΈΠ½Π°Ρ‚Π° Π·Π° ΠΏΠΎΡ‚ΠΎΡ†ΠΈ Π½Π° Redis ΠΈ ΠΈΠ·Π±ΠΎΡ€ Π½Π° нСзависима ΠΎΡ‚ Ρ€Π°ΠΌΠΊΠ°Ρ‚Π° Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ°

ΠΏΡ€Π΅Π΄Π³ΠΎΠ²ΠΎΡ€

ΠœΠΎΡΡ‚ уСбсайт, ΠΊΠΎΠΉΡ‚ΠΎ управлявам ΠΊΠ°Ρ‚ΠΎ Ρ…ΠΎΠ±ΠΈ, Π΅ ΠΏΡ€Π΅Π΄Π½Π°Π·Π½Π°Ρ‡Π΅Π½ Π΄Π° хоства интСрСсни Π½Π°Ρ‡Π°Π»Π½ΠΈ страници ΠΈ Π»ΠΈΡ‡Π½ΠΈ сайтовС. Π’Π°Π·ΠΈ Ρ‚Π΅ΠΌΠ° Π·Π°ΠΏΠΎΡ‡Π½Π° Π΄Π° ΠΌΠ΅ интСрСсува Π² самото Π½Π°Ρ‡Π°Π»ΠΎ Π½Π° ΠΌΠΎΠ΅Ρ‚ΠΎ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΈΡ€Π°Π½Π΅; Π² Ρ‚ΠΎΠ·ΠΈ ΠΌΠΎΠΌΠ΅Π½Ρ‚ бях ΠΎΡ‡Π°Ρ€ΠΎΠ²Π°Π½ ΠΎΡ‚ Π½Π°ΠΌΠΈΡ€Π°Π½Π΅Ρ‚ΠΎ Π½Π° страхотни профСсионалисти, ΠΊΠΎΠΈΡ‚ΠΎ ΠΏΠΈΡˆΠ°Ρ‚ Π·Π° сСбС си, своитС Ρ…ΠΎΠ±ΠΈΡ‚Π° ΠΈ ΠΏΡ€ΠΎΠ΅ΠΊΡ‚ΠΈ. ΠΠ°Π²ΠΈΠΊΡŠΡ‚ Π΄Π° Π³ΠΈ ΠΎΡ‚ΠΊΡ€ΠΈΠ²Π°ΠΌ Π·Π° сСбС си остава ΠΈ Π΄ΠΎ днСс: Π½Π° ΠΏΠΎΡ‡Ρ‚ΠΈ всСки комСрсиалСн ΠΈ Π½Π΅ ΠΌΠ½ΠΎΠ³ΠΎ комСрсиалСн сайт ΠΏΡ€ΠΎΠ΄ΡŠΠ»ΠΆΠ°Π²Π°ΠΌ Π΄Π° Π³Π»Π΅Π΄Π°ΠΌ Π² долния ΠΊΠΎΠ»ΠΎΠ½Ρ‚ΠΈΡ‚ΡƒΠ» Π² Ρ‚ΡŠΡ€ΡΠ΅Π½Π΅ Π½Π° Π²Ρ€ΡŠΠ·ΠΊΠΈ към Π°Π²Ρ‚ΠΎΡ€ΠΈΡ‚Π΅.

ΠžΡΡŠΡ‰Π΅ΡΡ‚Π²ΡΠ²Π°Π½Π΅ Π½Π° идСята

ΠŸΡŠΡ€Π²Π°Ρ‚Π° вСрсия бСшС просто html страница Π½Π° моя Π»ΠΈΡ‡Π΅Π½ уСбсайт, ΠΊΡŠΠ΄Π΅Ρ‚ΠΎ поставих Π²Ρ€ΡŠΠ·ΠΊΠΈ с подписи Π² ul списък. Π‘Π»Π΅Π΄ ΠΊΠ°Ρ‚ΠΎ написах 20 страници Π·Π° ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½ ΠΏΠ΅Ρ€ΠΈΠΎΠ΄ ΠΎΡ‚ Π²Ρ€Π΅ΠΌΠ΅, Π·Π°ΠΏΠΎΡ‡Π½Π°Ρ… Π΄Π° мисля, Ρ‡Π΅ Ρ‚ΠΎΠ²Π° Π½Π΅ Π΅ ΠΌΠ½ΠΎΠ³ΠΎ Π΅Ρ„Π΅ΠΊΡ‚ΠΈΠ²Π½ΠΎ ΠΈ Ρ€Π΅ΡˆΠΈΡ… Π΄Π° ΠΎΠΏΠΈΡ‚Π°ΠΌ Π΄Π° Π°Π²Ρ‚ΠΎΠΌΠ°Ρ‚ΠΈΠ·ΠΈΡ€Π°ΠΌ процСса. Π’ stackoverflow забСлязах, Ρ‡Π΅ ΠΌΠ½ΠΎΠ³ΠΎ Ρ…ΠΎΡ€Π° посочват сайтовС Π² ΠΏΡ€ΠΎΡ„ΠΈΠ»ΠΈΡ‚Π΅ си, Π·Π°Ρ‚ΠΎΠ²Π° написах Π°Π½Π°Π»ΠΈΠ·Π°Ρ‚ΠΎΡ€ Π½Π° php, ΠΊΠΎΠΉΡ‚ΠΎ просто ΠΏΡ€Π΅ΠΌΠΈΠ½Π° ΠΏΡ€Π΅Π· ΠΏΡ€ΠΎΡ„ΠΈΠ»ΠΈΡ‚Π΅, Π·Π°ΠΏΠΎΡ‡Π²Π°ΠΉΠΊΠΈ с ΠΏΡŠΡ€Π²ΠΈΡ (адрСситС Π½Π° SO Π΄ΠΎ Π΄Π΅Π½ днСшСн са Ρ‚Π°ΠΊΠ°: `/users/1` ), ΠΈΠ·Π²Π»Π΅Ρ‡Π΅ Π²Ρ€ΡŠΠ·ΠΊΠΈ ΠΎΡ‚ ТСлания Ρ‚Π°Π³ ΠΈ Π³ΠΎ Π΄ΠΎΠ±Π°Π²ΠΈ Π² SQLite.

Π’ΠΎΠ²Π° ΠΌΠΎΠΆΠ΅ Π΄Π° сС Π½Π°Ρ€Π΅Ρ‡Π΅ Π²Ρ‚ΠΎΡ€Π°Ρ‚Π° вСрсия: колСкция ΠΎΡ‚ дСсСтки хиляди URL адрСси Π² SQLite Ρ‚Π°Π±Π»ΠΈΡ†Π°, която Π·Π°ΠΌΠ΅Π½ΠΈ статичния списък Π² HTML. Направих просто Ρ‚ΡŠΡ€ΡΠ΅Π½Π΅ Π² Ρ‚ΠΎΠ·ΠΈ списък. Π·Π°Ρ‰ΠΎΡ‚ΠΎ имашС само URL адрСси, Ρ‚ΠΎΠ³Π°Π²Π° Ρ‚ΡŠΡ€ΡΠ΅Π½Π΅Ρ‚ΠΎ бСшС просто Π±Π°Π·ΠΈΡ€Π°Π½ΠΎ Π½Π° тях.

На Ρ‚ΠΎΠ·ΠΈ Π΅Ρ‚Π°ΠΏ изоставих ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Π° ΠΈ сС Π²ΡŠΡ€Π½Π°Ρ… към Π½Π΅Π³ΠΎ слСд дълго Π²Ρ€Π΅ΠΌΠ΅. На Ρ‚ΠΎΠ·ΠΈ Π΅Ρ‚Π°ΠΏ трудовият ΠΌΠΈ стаТ бСшС Π²Π΅Ρ‡Π΅ Π½Π°Π΄ Ρ‚Ρ€ΠΈ Π³ΠΎΠ΄ΠΈΠ½ΠΈ ΠΈ усСтих, Ρ‡Π΅ ΠΌΠΎΠ³Π° Π΄Π° сС Π·Π°Π½ΠΈΠΌΠ°Π²Π°ΠΌ с Π½Π΅Ρ‰ΠΎ ΠΏΠΎ-сСриозно. ОсвСн Ρ‚ΠΎΠ²Π° имашС голямо ΠΆΠ΅Π»Π°Π½ΠΈΠ΅ Π΄Π° сС овладСят сравнитСлно Π½ΠΎΠ²ΠΈ Ρ‚Π΅Ρ…Π½ΠΎΠ»ΠΎΠ³ΠΈΠΈ.

Π‘ΡŠΠ²Ρ€Π΅ΠΌΠ΅Π½Π½Π° вСрсия

ΠŸΡ€ΠΎΠ΅ΠΊΡ‚ Ρ€Π°Π·Π³ΡŠΡ€Π½Π°Ρ‚Π° Π² Docker, Π±Π°Π·Π°Ρ‚Π° Π΄Π°Π½Π½ΠΈ бСшС ΠΏΡ€Π΅Ρ…Π²ΡŠΡ€Π»Π΅Π½Π° към mongoDb, Π° наскоро бСшС Π΄ΠΎΠ±Π°Π²Π΅Π½ radish, ΠΊΠΎΠΉΡ‚ΠΎ ΠΏΡŠΡ€Π²ΠΎΠ½Π°Ρ‡Π°Π»Π½ΠΎ бСшС само Π·Π° ΠΊΠ΅ΡˆΠΈΡ€Π°Π½Π΅. Π—Π° основа Π΅ ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°Π½Π° Π΅Π΄Π½Π° ΠΎΡ‚ PHP ΠΌΠΈΠΊΡ€ΠΎΡ€Π°ΠΌΠΊΠΈΡ‚Π΅.

ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌ

НовитС сайтовС сС добавят ΠΎΡ‚ ΠΊΠΎΠ½Π·ΠΎΠ»Π½Π° ΠΊΠΎΠΌΠ°Π½Π΄Π°, която синхронно ΠΏΡ€Π°Π²ΠΈ слСдното:

  • Π˜Π·Ρ‚Π΅Π³Π»Ρ ΡΡŠΠ΄ΡŠΡ€ΠΆΠ°Π½ΠΈΠ΅ ΠΏΠΎ URL
  • Π—Π°Π΄Π°Π²Π° Ρ„Π»Π°Π³, ΠΏΠΎΠΊΠ°Π·Π²Π°Ρ‰ Π΄Π°Π»ΠΈ HTTPS Π΅ Π½Π°Π»ΠΈΡ‡Π΅Π½
  • Π—Π°ΠΏΠ°Π·Π²Π° ΡΡŠΡ‰Π½ΠΎΡΡ‚Ρ‚Π° Π½Π° уСбсайта
  • Π˜Π·Ρ…ΠΎΠ΄Π½ΠΈΡΡ‚ HTML ΠΈ Π·Π°Π³Π»Π°Π²ΠΊΠΈΡ‚Π΅ сС Π·Π°ΠΏΠ°Π·Π²Π°Ρ‚ Π² историята Π½Π° β€žΠΈΠ½Π΄Π΅ΠΊΡΠΈΡ€Π°Π½Π΅Ρ‚ΠΎβ€œ.
  • Анализира ΡΡŠΠ΄ΡŠΡ€ΠΆΠ°Π½ΠΈΠ΅Ρ‚ΠΎ, ΠΈΠ·Π²Π»ΠΈΡ‡Π° Π·Π°Π³Π»Π°Π²ΠΈΠ΅ ΠΈ описаниС
  • Записва Π΄Π°Π½Π½ΠΈ Π² ΠΎΡ‚Π΄Π΅Π»Π½Π° колСкция

Π’ΠΎΠ²Π° бСшС Π΄ΠΎΡΡ‚Π°Ρ‚ΡŠΡ‡Π½ΠΎ просто Π΄Π° ΡΡŠΡ…Ρ€Π°Π½ΡΠ²Π°Ρ‚Π΅ сайтовС ΠΈ Π΄Π° Π³ΠΈ ΠΏΠΎΠΊΠ°Π·Π²Π°Ρ‚Π΅ Π² списък:

ΠŸΡ€Π΅Ρ…Π²ΡŠΡ€Π»ΡΠ½Π΅ Π½Π° Π±Π΅ΠΊΠ΅Π½Π΄Π° Π½Π° PHP към ΡˆΠΈΠ½Π°Ρ‚Π° Π·Π° ΠΏΠΎΡ‚ΠΎΡ†ΠΈ Π½Π° Redis ΠΈ ΠΈΠ·Π±ΠΎΡ€ Π½Π° нСзависима ΠΎΡ‚ Ρ€Π°ΠΌΠΊΠ°Ρ‚Π° Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ°

Но идСята Π·Π° Π°Π²Ρ‚ΠΎΠΌΠ°Ρ‚ΠΈΡ‡Π½ΠΎ индСксиранС, ΠΊΠ°Ρ‚Π΅Π³ΠΎΡ€ΠΈΠ·ΠΈΡ€Π°Π½Π΅ ΠΈ класиранС Π½Π° всичко, ΠΏΠΎΠ΄Π΄ΡŠΡ€ΠΆΠ°Π½Π΅ Π½Π° всичко Π°ΠΊΡ‚ΡƒΠ°Π»Π½ΠΎ, Π½Π΅ сС вписва Π΄ΠΎΠ±Ρ€Π΅ Π² Ρ‚Π°Π·ΠΈ ΠΏΠ°Ρ€Π°Π΄ΠΈΠ³ΠΌΠ°. Π”ΠΎΡ€ΠΈ простото добавянС Π½Π° ΡƒΠ΅Π± ΠΌΠ΅Ρ‚ΠΎΠ΄ Π·Π° добавянС Π½Π° страници изисква Π΄ΡƒΠ±Π»ΠΈΡ€Π°Π½Π΅ Π½Π° ΠΊΠΎΠ΄ ΠΈ Π±Π»ΠΎΠΊΠΈΡ€Π°Π½Π΅, Π·Π° Π΄Π° сС ΠΈΠ·Π±Π΅Π³Π½Π΅ ΠΏΠΎΡ‚Π΅Π½Ρ†ΠΈΠ°Π»Π΅Π½ DDoS.

ΠšΠ°Ρ‚ΠΎ цяло, Ρ€Π°Π·Π±ΠΈΡ€Π° сС, всичко ΠΌΠΎΠΆΠ΅ Π΄Π° сС Π½Π°ΠΏΡ€Π°Π²ΠΈ синхронно ΠΈ Π² ΡƒΠ΅Π± ΠΌΠ΅Ρ‚ΠΎΠ΄Π° ΠΌΠΎΠΆΠ΅Ρ‚Π΅ просто Π΄Π° Π·Π°ΠΏΠ°Π·ΠΈΡ‚Π΅ URL адрСса, Ρ‚Π°ΠΊΠ° Ρ‡Π΅ чудовищният Π΄Π΅ΠΌΠΎΠ½ Π΄Π° изпълнява всички Π·Π°Π΄Π°Ρ‡ΠΈ Π·Π° URL адрСситС ΠΎΡ‚ списъка. Но всС ΠΏΠ°ΠΊ ΠΈ Ρ‚ΡƒΠΊ Π΄ΡƒΠΌΠ°Ρ‚Π° β€žΠΎΠΏΠ°ΡˆΠΊΠ°β€œ сС Π½Π°ΠΌΠ΅ΠΊΠ²Π°. И Π°ΠΊΠΎ Π΅ Π²Π½Π΅Π΄Ρ€Π΅Π½Π° опашка, Ρ‚ΠΎΠ³Π°Π²Π° всички Π·Π°Π΄Π°Ρ‡ΠΈ ΠΌΠΎΠ³Π°Ρ‚ Π΄Π° Π±ΡŠΠ΄Π°Ρ‚ Ρ€Π°Π·Π΄Π΅Π»Π΅Π½ΠΈ ΠΈ изпълнявани ΠΏΠΎΠ½Π΅ асинхронно.

РСшСниС

Π’Π½Π΅Π΄Ρ€Π΅Ρ‚Π΅ опашки ΠΈ Π½Π°ΠΏΡ€Π°Π²Π΅Ρ‚Π΅ управлявана ΠΎΡ‚ ΡΡŠΠ±ΠΈΡ‚ΠΈΡ систСма Π·Π° ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠ° Π½Π° всички Π·Π°Π΄Π°Ρ‡ΠΈ. И ΠΎΡ‚Π΄Π°Π²Π½Π° исках Π΄Π° ΠΏΡ€ΠΎΠ±Π²Π°ΠΌ Redis Streams.

ИзползванС Π½Π° Redis ΠΏΠΎΡ‚ΠΎΡ†ΠΈ Π² PHP

Π·Π°Ρ‰ΠΎΡ‚ΠΎ Въй ΠΊΠ°Ρ‚ΠΎ моята Ρ€Π°ΠΌΠΊΠ° Π½Π΅ Π΅ Π΅Π΄Π½Π° ΠΎΡ‚ Ρ‚Ρ€ΠΈΡ‚Π΅ Π³ΠΈΠ³Π°Π½Ρ‚Π° Symfony, Laravel, Yii, Π±ΠΈΡ… искал Π΄Π° намСря нСзависима Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ°. Но, ΠΊΠ°ΠΊΡ‚ΠΎ сС ΠΎΠΊΠ°Π·Π° (ΠΏΡ€ΠΈ ΠΏΡŠΡ€Π²ΠΈΡ ΠΏΡ€Π΅Π³Π»Π΅Π΄), Π΅ нСвъзмоТно Π΄Π° сС намСрят ΠΎΡ‚Π΄Π΅Π»Π½ΠΈ сСриозни Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠΈ. Всичко, ΡΠ²ΡŠΡ€Π·Π°Π½ΠΎ с ΠΎΠΏΠ°ΡˆΠΊΠΈΡ‚Π΅, Π΅ ΠΈΠ»ΠΈ ΠΏΡ€ΠΎΠ΅ΠΊΡ‚ ΠΎΡ‚ 3 ΠΊΠΎΠΌΠΈΡ‚Π° ΠΏΡ€Π΅Π΄ΠΈ ΠΏΠ΅Ρ‚ Π³ΠΎΠ΄ΠΈΠ½ΠΈ, ΠΈΠ»ΠΈ Π΅ ΠΎΠ±Π²ΡŠΡ€Π·Π°Π½ΠΎ с Ρ€Π°ΠΌΠΊΠ°Ρ‚Π°.

Π§ΡƒΠ²Π°Π» съм ΠΌΠ½ΠΎΠ³ΠΎ Π·Π° Symfony ΠΊΠ°Ρ‚ΠΎ доставчик Π½Π° ΠΎΡ‚Π΄Π΅Π»Π½ΠΈ ΠΏΠΎΠ»Π΅Π·Π½ΠΈ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ΠΈ ΠΈ Π²Π΅Ρ‡Π΅ ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°ΠΌ някои ΠΎΡ‚ тях. А ΡΡŠΡ‰ΠΎ Ρ‚Π°ΠΊΠ° някои Π½Π΅Ρ‰Π° ΠΎΡ‚ Laravel ΡΡŠΡ‰ΠΎ ΠΌΠΎΠ³Π°Ρ‚ Π΄Π° сС ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°Ρ‚, Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€ ORM, Π±Π΅Π· Π½Π°Π»ΠΈΡ‡ΠΈΠ΅Ρ‚ΠΎ Π½Π° самата Ρ€Π°ΠΌΠΊΠ°.

symfony/messenger

ΠŸΡŠΡ€Π²ΠΈΡΡ‚ ΠΊΠ°Π½Π΄ΠΈΠ΄Π°Ρ‚ Π²Π΅Π΄Π½Π°Π³Π° изглСТдашС ΠΈΠ΄Π΅Π°Π»Π΅Π½ ΠΈ Π±Π΅Π· съмнСниС Π³ΠΎ инсталирах. Но сС ΠΎΠΊΠ°Π·Π° ΠΏΠΎ-Ρ‚Ρ€ΡƒΠ΄Π½ΠΎ Π΄Π° сС Ρ‚ΡŠΡ€ΡΡΡ‚ Π² Google ΠΏΡ€ΠΈΠΌΠ΅Ρ€ΠΈ Π·Π° ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°Π½Π΅ извън Symfony. Как Π΄Π° сС сглоби ΠΎΡ‚ ΠΊΡƒΠΏ класовС с унивСрсални, бСзсмислСни ΠΈΠΌΠ΅Π½Π°, автобус Π·Π° ΠΏΡ€Π΅Π΄Π°Π²Π°Π½Π΅ Π½Π° ΡΡŠΠΎΠ±Ρ‰Π΅Π½ΠΈΡ ΠΈ Π΄ΠΎΡ€ΠΈ Π½Π° Redis?

ΠŸΡ€Π΅Ρ…Π²ΡŠΡ€Π»ΡΠ½Π΅ Π½Π° Π±Π΅ΠΊΠ΅Π½Π΄Π° Π½Π° PHP към ΡˆΠΈΠ½Π°Ρ‚Π° Π·Π° ΠΏΠΎΡ‚ΠΎΡ†ΠΈ Π½Π° Redis ΠΈ ΠΈΠ·Π±ΠΎΡ€ Π½Π° нСзависима ΠΎΡ‚ Ρ€Π°ΠΌΠΊΠ°Ρ‚Π° Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ°

ДокумСнтацията Π½Π° официалния сайт бСшС доста ΠΏΠΎΠ΄Ρ€ΠΎΠ±Π½Π°, Π½ΠΎ инициализацията бСшС описана само Π·Π° Symfony, ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°ΠΉΠΊΠΈ тСхния любим YML ΠΈ Π΄Ρ€ΡƒΠ³ΠΈ магичСски ΠΌΠ΅Ρ‚ΠΎΠ΄ΠΈ Π·Π° Π½Π΅-симфонист. Нямах интСрСс към самия процСс Π½Π° инсталиранС, особСно ΠΏΠΎ Π²Ρ€Π΅ΠΌΠ΅ Π½Π° Π½ΠΎΠ²ΠΎΠ³ΠΎΠ΄ΠΈΡˆΠ½ΠΈΡ‚Π΅ ΠΏΡ€Π°Π·Π½ΠΈΡ†ΠΈ. Но Ρ‚Ρ€ΡΠ±Π²Π°ΡˆΠ΅ Π΄Π° правя Ρ‚ΠΎΠ²Π° Π½Π΅ΠΎΡ‡Π°ΠΊΠ²Π°Π½ΠΎ дълго Π²Ρ€Π΅ΠΌΠ΅.

ΠžΠΏΠΈΡ‚ΡŠΡ‚ Π΄Π° Ρ€Π°Π·Π±Π΅Ρ€Π΅Ρ‚Π΅ ΠΊΠ°ΠΊ Π΄Π° ΡΡŠΠ·Π΄Π°Π΄Π΅Ρ‚Π΅ инстанция Π½Π° систСма, ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°ΠΉΠΊΠΈ ΠΈΠ·Ρ‚ΠΎΡ‡Π½ΠΈΡ†ΠΈ Π½Π° Symfony, ΡΡŠΡ‰ΠΎ Π½Π΅ Π΅ Π½Π°ΠΉ-Ρ‚Ρ€ΠΈΠ²ΠΈΠ°Π»Π½Π°Ρ‚Π° Π·Π°Π΄Π°Ρ‡Π° Π·Π° ΠΊΡ€Π°Ρ‚ΡŠΠΊ срок:

ΠŸΡ€Π΅Ρ…Π²ΡŠΡ€Π»ΡΠ½Π΅ Π½Π° Π±Π΅ΠΊΠ΅Π½Π΄Π° Π½Π° PHP към ΡˆΠΈΠ½Π°Ρ‚Π° Π·Π° ΠΏΠΎΡ‚ΠΎΡ†ΠΈ Π½Π° Redis ΠΈ ΠΈΠ·Π±ΠΎΡ€ Π½Π° нСзависима ΠΎΡ‚ Ρ€Π°ΠΌΠΊΠ°Ρ‚Π° Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ°

Π‘Π»Π΅Π΄ ΠΊΠ°Ρ‚ΠΎ сС Π·Π°Ρ€ΠΎΠ²ΠΈΡ… във всичко Ρ‚ΠΎΠ²Π° ΠΈ сС ΠΎΠΏΠΈΡ‚Π°Ρ… Π΄Π° направя Π½Π΅Ρ‰ΠΎ с Ρ€ΡŠΡ†Π΅Ρ‚Π΅ си, стигнах Π΄ΠΎ ΠΈΠ·Π²ΠΎΠ΄Π°, Ρ‡Π΅ правя някакви ΠΏΠ°Ρ‚Π΅Ρ€ΠΈΡ†ΠΈ ΠΈ Ρ€Π΅ΡˆΠΈΡ… Π΄Π° ΠΎΠΏΠΈΡ‚Π°ΠΌ Π½Π΅Ρ‰ΠΎ Π΄Ρ€ΡƒΠ³ΠΎ.

освСтСни/опашка

Оказа сС, Ρ‡Π΅ Ρ‚Π°Π·ΠΈ Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ° Π΅ тясно ΡΠ²ΡŠΡ€Π·Π°Π½Π° с инфраструктурата Π½Π° Laravel ΠΈ ΠΊΡƒΠΏ Π΄Ρ€ΡƒΠ³ΠΈ зависимости, Ρ‚Π°ΠΊΠ° Ρ‡Π΅ Π½Π΅ ΠΎΡ‚Π΄Π΅Π»ΠΈΡ… ΠΌΠ½ΠΎΠ³ΠΎ Π²Ρ€Π΅ΠΌΠ΅ Π·Π° нСя: инсталирах я, ΠΏΠΎΠ³Π»Π΅Π΄Π½Π°Ρ… я, видях зависимоститС ΠΈ я ΠΈΠ·Ρ‚Ρ€ΠΈΡ….

yiisoft/yii2-опашка

Π•, Ρ‚ΡƒΠΊ Π²Π΅Π΄Π½Π°Π³Π° сС ΠΏΡ€Π΅Π΄ΠΏΠΎΠ»ΠΎΠΆΠΈ ΠΎΡ‚ ΠΈΠΌΠ΅Ρ‚ΠΎ, ΠΎΡ‚Π½ΠΎΠ²ΠΎ, строга Π²Ρ€ΡŠΠ·ΠΊΠ° с Yii2. Π’Ρ€ΡΠ±Π²Π°ΡˆΠ΅ Π΄Π° ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°ΠΌ Ρ‚Π°Π·ΠΈ Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ° ΠΈ Π½Π΅ бСшС лошо, Π½ΠΎ Π½Π΅ сС замислих, Ρ‡Π΅ зависи напълно ΠΎΡ‚ Yii2.

ΠžΡΡ‚Π°Π½Π°Π»ΠΈΡ‚Π΅

Всичко останало, ΠΊΠΎΠ΅Ρ‚ΠΎ Π½Π°ΠΌΠ΅Ρ€ΠΈΡ… Π² GitHub, бяха Π½Π΅Π½Π°Π΄Π΅ΠΆΠ΄Π½ΠΈ, остарСли ΠΈ изоставСни ΠΏΡ€ΠΎΠ΅ΠΊΡ‚ΠΈ Π±Π΅Π· Π·Π²Π΅Π·Π΄ΠΈ, Ρ„ΠΎΡ€ΠΊΠΎΠ²Π΅ ΠΈ голям Π±Ρ€ΠΎΠΉ Π°Π½Π³Π°ΠΆΠΈΠΌΠ΅Π½Ρ‚ΠΈ.

Π’ΡŠΡ€Π½Π΅Ρ‚Π΅ сС към symfony/messenger, тСхничСски подробности

Π’Ρ€ΡΠ±Π²Π°ΡˆΠ΅ Π΄Π° Ρ€Π°Π·Π±Π΅Ρ€Π° Ρ‚Π°Π·ΠΈ Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ° ΠΈ слСд ΠΊΠ°Ρ‚ΠΎ ΠΏΡ€Π΅ΠΊΠ°Ρ€Π°Ρ… ΠΎΡ‰Π΅ извСстно Π²Ρ€Π΅ΠΌΠ΅, успях. Оказа сС, Ρ‡Π΅ всичко Π΅ съвсСм ΠΊΡ€Π°Ρ‚ΠΊΠΎ ΠΈ просто. Π—Π° Π΄Π° създам автобуса, Π½Π°ΠΏΡ€Π°Π²ΠΈΡ… ΠΌΠ°Π»ΠΊΠ° Ρ„Π°Π±Ρ€ΠΈΠΊΠ°, Π·Π°Ρ‰ΠΎΡ‚ΠΎ... Π’Ρ€ΡΠ±Π²Π°ΡˆΠ΅ Π΄Π° ΠΈΠΌΠ°ΠΌ няколко Π³ΡƒΠΌΠΈ ΠΈ с Ρ€Π°Π·Π»ΠΈΡ‡Π½ΠΈ ΠΌΠ°Π½ΠΈΠΏΡƒΠ»Π°Ρ‚ΠΎΡ€ΠΈ.

ΠŸΡ€Π΅Ρ…Π²ΡŠΡ€Π»ΡΠ½Π΅ Π½Π° Π±Π΅ΠΊΠ΅Π½Π΄Π° Π½Π° PHP към ΡˆΠΈΠ½Π°Ρ‚Π° Π·Π° ΠΏΠΎΡ‚ΠΎΡ†ΠΈ Π½Π° Redis ΠΈ ΠΈΠ·Π±ΠΎΡ€ Π½Π° нСзависима ΠΎΡ‚ Ρ€Π°ΠΌΠΊΠ°Ρ‚Π° Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ°

Π‘Π°ΠΌΠΎ няколко ΡΡ‚ΡŠΠΏΠΊΠΈ:

  • НиС създавамС ΠΌΠ°Π½ΠΈΠΏΡƒΠ»Π°Ρ‚ΠΎΡ€ΠΈ Π½Π° ΡΡŠΠΎΠ±Ρ‰Π΅Π½ΠΈΡ, ΠΊΠΎΠΈΡ‚ΠΎ трябва Π΄Π° ΠΌΠΎΠ³Π°Ρ‚ просто Π΄Π° сС ΠΈΠ·Π²ΠΈΠΊΠ²Π°Ρ‚
  • ОбвивамС Π³ΠΈ Π² HandlerDescriptor (клас ΠΎΡ‚ Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ°Ρ‚Π°)
  • НиС ΠΎΠ±Π²ΠΈΠ²Π°ΠΌΠ΅ Ρ‚Π΅Π·ΠΈ β€žΠ΄Π΅ΡΠΊΡ€ΠΈΠΏΡ‚ΠΎΡ€ΠΈβ€œ Π² СкзСмпляр Π½Π° HandlersLocator
  • ДобавянС Π½Π° HandlersLocator към СкзСмпляра Π½Π° MessageBus
  • ΠŸΡ€Π΅Π΄Π°Π²Π°ΠΌΠ΅ Π½Π°Π±ΠΎΡ€ ΠΎΡ‚ `SenderInterface` към SendersLocator, Π² моя случай СкзСмпляри Π½Π° `RedisTransport` класовС, ΠΊΠΎΠΈΡ‚ΠΎ са ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€ΠΈΡ€Π°Π½ΠΈ ΠΏΠΎ ΠΎΡ‡Π΅Π²ΠΈΠ΄Π΅Π½ Π½Π°Ρ‡ΠΈΠ½
  • ДобавянС Π½Π° SendersLocator към СкзСмпляра Π½Π° MessageBus

MessageBus ΠΈΠΌΠ° ΠΌΠ΅Ρ‚ΠΎΠ΄ `->dispatch()`, ΠΊΠΎΠΉΡ‚ΠΎ Ρ‚ΡŠΡ€ΡΠΈ подходящитС ΠΌΠ°Π½ΠΈΠΏΡƒΠ»Π°Ρ‚ΠΎΡ€ΠΈ Π² HandlersLocator ΠΈ ΠΈΠΌ ΠΏΡ€Π΅Π΄Π°Π²Π° ΡΡŠΠΎΠ±Ρ‰Π΅Π½ΠΈΠ΅Ρ‚ΠΎ, ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°ΠΉΠΊΠΈ ΡΡŠΠΎΡ‚Π²Π΅Ρ‚Π½ΠΈΡ `SenderInterface` Π·Π° ΠΈΠ·ΠΏΡ€Π°Ρ‰Π°Π½Π΅ ΠΏΡ€Π΅Π· ΡˆΠΈΠ½Π°Ρ‚Π° (Redis ΠΏΠΎΡ‚ΠΎΡ†ΠΈ).

Π’ конфигурацията Π½Π° ΠΊΠΎΠ½Ρ‚Π΅ΠΉΠ½Π΅Ρ€Π° (Π² Ρ‚ΠΎΠ·ΠΈ случай php-di), цСлият Ρ‚ΠΎΠ·ΠΈ ΠΏΠ°ΠΊΠ΅Ρ‚ ΠΌΠΎΠΆΠ΅ Π΄Π° бъдС ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€ΠΈΡ€Π°Π½ ΠΏΠΎ слСдния Π½Π°Ρ‡ΠΈΠ½:

        CONTAINER_REDIS_TRANSPORT_SECRET => function (ContainerInterface $c) {
            return new RedisTransport(
                $c->get(CONTAINER_REDIS_STREAM_CONNECTION_SECRET),
                $c->get(CONTAINER_SERIALIZER))
            ;
        },
        CONTAINER_REDIS_TRANSPORT_LOG => function (ContainerInterface $c) {
            return new RedisTransport(
                $c->get(CONTAINER_REDIS_STREAM_CONNECTION_LOG),
                $c->get(CONTAINER_SERIALIZER))
            ;
        },
        CONTAINER_REDIS_STREAM_RECEIVER_SECRET => function (ContainerInterface $c) {
            return new RedisReceiver(
                $c->get(CONTAINER_REDIS_STREAM_CONNECTION_SECRET),
                $c->get(CONTAINER_SERIALIZER)
            );
        },
        CONTAINER_REDIS_STREAM_RECEIVER_LOG => function (ContainerInterface $c) {
            return new RedisReceiver(
                $c->get(CONTAINER_REDIS_STREAM_CONNECTION_LOG),
                $c->get(CONTAINER_SERIALIZER)
            );
        },
        CONTAINER_REDIS_STREAM_BUS => function (ContainerInterface $c) {
            $sendersLocator = new SendersLocator([
                AppMessagesSecretJsonMessages::class => [CONTAINER_REDIS_TRANSPORT_SECRET],
                AppMessagesDaemonLogMessage::class => [CONTAINER_REDIS_TRANSPORT_LOG],
            ], $c);
            $middleware[] = new SendMessageMiddleware($sendersLocator);

            return new MessageBus($middleware);
        },
        CONTAINER_REDIS_STREAM_CONNECTION_SECRET => function (ContainerInterface $c) {
            $host = 'bu-02-redis';
            $port = 6379;
            $dsn = "redis://$host:$port";
            $options = [
                'stream' => 'secret',
                'group' => 'default',
                'consumer' => 'default',
            ];

            return Connection::fromDsn($dsn, $options);
        },
        CONTAINER_REDIS_STREAM_CONNECTION_LOG => function (ContainerInterface $c) {
            $host = 'bu-02-redis';
            $port = 6379;
            $dsn = "redis://$host:$port";
            $options = [
                'stream' => 'log',
                'group' => 'default',
                'consumer' => 'default',
            ];

            return Connection::fromDsn($dsn, $options);
        },

Π’ΡƒΠΊ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ Π΄Π° Π²ΠΈΠ΄ΠΈΡ‚Π΅, Ρ‡Π΅ Π² SendersLocator смС Π·Π°Π΄Π°Π»ΠΈ Ρ€Π°Π·Π»ΠΈΡ‡Π½ΠΈ β€žΡ‚Ρ€Π°Π½ΡΠΏΠΎΡ€Ρ‚ΠΈβ€œ Π·Π° Π΄Π²Π΅ Ρ€Π°Π·Π»ΠΈΡ‡Π½ΠΈ ΡΡŠΠΎΠ±Ρ‰Π΅Π½ΠΈΡ, всяко ΠΎΡ‚ ΠΊΠΎΠΈΡ‚ΠΎ ΠΈΠΌΠ° своя собствСна Π²Ρ€ΡŠΠ·ΠΊΠ° към ΡΡŠΠΎΡ‚Π²Π΅Ρ‚Π½ΠΈΡ‚Π΅ ΠΏΠΎΡ‚ΠΎΡ†ΠΈ.

Направих ΠΎΡ‚Π΄Π΅Π»Π΅Π½ дСмонстрационСн ΠΏΡ€ΠΎΠ΅ΠΊΡ‚, дСмонстриращ ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ Π½Π° Ρ‚Ρ€ΠΈ Π΄Π΅ΠΌΠΎΠ½Π°, ΠΊΠΎΠΌΡƒΠ½ΠΈΠΊΠΈΡ€Π°Ρ‰ΠΈ ΠΏΠΎΠΌΠ΅ΠΆΠ΄Ρƒ си, ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°ΠΉΠΊΠΈ слСдната шина: https://github.com/backend-university/products/tree/master/products/02-redis-streams-bus.

Но Ρ‰Π΅ Π²ΠΈ ΠΏΠΎΠΊΠ°ΠΆΠ° ΠΊΠ°ΠΊ потрСбитСлят ΠΌΠΎΠΆΠ΅ Π΄Π° бъдС структуриран:

use AppMessagesDaemonLogMessage;
use SymfonyComponentMessengerHandlerHandlerDescriptor;
use SymfonyComponentMessengerHandlerHandlersLocator;
use SymfonyComponentMessengerMessageBus;
use SymfonyComponentMessengerMiddlewareHandleMessageMiddleware;
use SymfonyComponentMessengerMiddlewareSendMessageMiddleware;
use SymfonyComponentMessengerTransportSenderSendersLocator;

require_once __DIR__ . '/../vendor/autoload.php';
/** @var PsrContainerContainerInterface $container */
$container = require_once('config/container.php');

$handlers = [
    DaemonLogMessage::class => [
        new HandlerDescriptor(
            function (DaemonLogMessage $m) {
                error_log('DaemonLogHandler: message handled: / ' . $m->getMessage());
            },
            ['from_transport' => CONTAINER_REDIS_TRANSPORT_LOG]
        )
    ],
];
$middleware = [];
$middleware[] = new HandleMessageMiddleware(new HandlersLocator($handlers));
$sendersLocator = new SendersLocator(['*' => [CONTAINER_REDIS_TRANSPORT_LOG]], $container);
$middleware[] = new SendMessageMiddleware($sendersLocator);

$bus = new MessageBus($middleware);
$receivers = [
    CONTAINER_REDIS_TRANSPORT_LOG => $container->get(CONTAINER_REDIS_STREAM_RECEIVER_LOG),
];
$w = new SymfonyComponentMessengerWorker($receivers, $bus, $container->get(CONTAINER_EVENT_DISPATCHER));
$w->run();

ИзползванС Π½Π° Ρ‚Π°Π·ΠΈ инфраструктура Π² ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅

Π‘Π»Π΅Π΄ ΠΊΠ°Ρ‚ΠΎ Π²Π½Π΅Π΄Ρ€ΠΈΡ… ΡˆΠΈΠ½Π°Ρ‚Π° Π² моя Π±Π΅ΠΊΠ΅Π½Π΄, ΠΎΡ‚Π΄Π΅Π»ΠΈΡ… ΠΎΡ‚Π΄Π΅Π»Π½ΠΈ Π΅Ρ‚Π°ΠΏΠΈ ΠΎΡ‚ старата синхронна ΠΊΠΎΠΌΠ°Π½Π΄Π° ΠΈ Π½Π°ΠΏΡ€Π°Π²ΠΈΡ… ΠΎΡ‚Π΄Π΅Π»Π½ΠΈ ΠΌΠ°Π½ΠΈΠΏΡƒΠ»Π°Ρ‚ΠΎΡ€ΠΈ, всСки ΠΎΡ‚ ΠΊΠΎΠΈΡ‚ΠΎ Π²ΡŠΡ€ΡˆΠΈ своСто собствСно Π½Π΅Ρ‰ΠΎ.

ΠšΠΎΠ½Π²Π΅ΠΉΠ΅Ρ€ΡŠΡ‚ Π·Π° добавянС Π½Π° Π½ΠΎΠ² сайт към Π±Π°Π·Π°Ρ‚Π° Π΄Π°Π½Π½ΠΈ изглСТдашС Ρ‚Π°ΠΊΠ°:

ΠŸΡ€Π΅Ρ…Π²ΡŠΡ€Π»ΡΠ½Π΅ Π½Π° Π±Π΅ΠΊΠ΅Π½Π΄Π° Π½Π° PHP към ΡˆΠΈΠ½Π°Ρ‚Π° Π·Π° ΠΏΠΎΡ‚ΠΎΡ†ΠΈ Π½Π° Redis ΠΈ ΠΈΠ·Π±ΠΎΡ€ Π½Π° нСзависима ΠΎΡ‚ Ρ€Π°ΠΌΠΊΠ°Ρ‚Π° Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ°

И Π²Π΅Π΄Π½Π°Π³Π° слСд Ρ‚ΠΎΠ²Π° ΠΌΠΈ стана ΠΌΠ½ΠΎΠ³ΠΎ ΠΏΠΎ-лСсно Π΄Π° добавя Π½ΠΎΠ²Π° функционалност, Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€ ΠΈΠ·Π²Π»ΠΈΡ‡Π°Π½Π΅ ΠΈ Π°Π½Π°Π»ΠΈΠ·ΠΈΡ€Π°Π½Π΅ Π½Π° Rss. Π·Π°Ρ‰ΠΎΡ‚ΠΎ Ρ‚ΠΎΠ·ΠΈ процСс ΡΡŠΡ‰ΠΎ изисква ΠΎΡ€ΠΈΠ³ΠΈΠ½Π°Π»Π½ΠΎΡ‚ΠΎ ΡΡŠΠ΄ΡŠΡ€ΠΆΠ°Π½ΠΈΠ΅, слСд ΠΊΠΎΠ΅Ρ‚ΠΎ ΠΌΠ°Π½ΠΈΠΏΡƒΠ»Π°Ρ‚ΠΎΡ€ΡŠΡ‚ Π·Π° ΠΈΠ·Π²Π»ΠΈΡ‡Π°Π½Π΅ Π½Π° RSS Π²Ρ€ΡŠΠ·ΠΊΠΈ, ΠΊΠ°Ρ‚ΠΎ WebsiteIndexHistoryPersistor, сС Π°Π±ΠΎΠ½ΠΈΡ€Π° Π·Π° ΡΡŠΠΎΠ±Ρ‰Π΅Π½ΠΈΠ΅Ρ‚ΠΎ β€žContent/HtmlContentβ€œ, ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Π²Π° Π³ΠΎ ΠΈ ΠΏΡ€Π΅Π΄Π°Π²Π° ΠΆΠ΅Π»Π°Π½ΠΎΡ‚ΠΎ ΡΡŠΠΎΠ±Ρ‰Π΅Π½ΠΈΠ΅ ΠΏΠΎ нСговия ΠΊΠΎΠ½Π²Π΅ΠΉΠ΅Ρ€ ΠΏΠΎ-Π½Π°Ρ‚Π°Ρ‚ΡŠΠΊ.

ΠŸΡ€Π΅Ρ…Π²ΡŠΡ€Π»ΡΠ½Π΅ Π½Π° Π±Π΅ΠΊΠ΅Π½Π΄Π° Π½Π° PHP към ΡˆΠΈΠ½Π°Ρ‚Π° Π·Π° ΠΏΠΎΡ‚ΠΎΡ†ΠΈ Π½Π° Redis ΠΈ ΠΈΠ·Π±ΠΎΡ€ Π½Π° нСзависима ΠΎΡ‚ Ρ€Π°ΠΌΠΊΠ°Ρ‚Π° Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ°

Π’ ΠΊΡ€Π°ΠΉΠ½Π° смСтка ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ…ΠΌΠ΅ няколко Π΄Π΅ΠΌΠΎΠ½Π°, всСки ΠΎΡ‚ ΠΊΠΎΠΈΡ‚ΠΎ ΠΏΠΎΠ΄Π΄ΡŠΡ€ΠΆΠ° Π²Ρ€ΡŠΠ·ΠΊΠΈ само с Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΈΡ‚Π΅ рСсурси. НапримСр Π΄Π΅ΠΌΠΎΠ½ дСтско ΠΊΠΎΠΌΠ±ΠΈΠ½ΠΈΠ·ΠΎΠ½Ρ‡Π΅ Π·Π° Π»Π°Π·Π΅Π½Π΅ ΡΡŠΠ΄ΡŠΡ€ΠΆΠ° всички ΠΌΠ°Π½ΠΈΠΏΡƒΠ»Π°Ρ‚ΠΎΡ€ΠΈ, ΠΊΠΎΠΈΡ‚ΠΎ изискват Π΄ΠΎΡΡ‚ΡŠΠΏ Π΄ΠΎ ΠΈΠ½Ρ‚Π΅Ρ€Π½Π΅Ρ‚ Π·Π° ΡΡŠΠ΄ΡŠΡ€ΠΆΠ°Π½ΠΈΠ΅, ΠΈ Π΄Π΅ΠΌΠΎΠ½Π° упорствам ΠΏΠΎΠ΄Π΄ΡŠΡ€ΠΆΠ° Π²Ρ€ΡŠΠ·ΠΊΠ° с Π±Π°Π·Π°Ρ‚Π° Π΄Π°Π½Π½ΠΈ.

Π‘Π΅Π³Π°, вмСсто Π΄Π° ΠΈΠ·Π±ΠΈΡ€Π°Ρ‚ ΠΎΡ‚ Π±Π°Π·Π°Ρ‚Π° Π΄Π°Π½Π½ΠΈ, Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΈΡ‚Π΅ ΠΈΠ΄Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ†ΠΈΠΎΠ½Π½ΠΈ Π½ΠΎΠΌΠ΅Ρ€Π° слСд вмъкванС ΠΎΡ‚ persister просто сС ΠΏΡ€Π΅Π΄Π°Π²Π°Ρ‚ ΠΏΡ€Π΅Π· автобуса Π΄ΠΎ всички заинтСрСсовани ΠΌΠ°Π½ΠΈΠΏΡƒΠ»Π°Ρ‚ΠΎΡ€ΠΈ.

Π˜Π·Ρ‚ΠΎΡ‡Π½ΠΈΠΊ: www.habr.com

ДобавянС Π½Π° Π½ΠΎΠ² ΠΊΠΎΠΌΠ΅Π½Ρ‚Π°Ρ€