«Детская школа искусств» Мошенского муниципального района

Reader афанасьева: Верещагина И., Афанасьева О.: English Reader. Английский язык. Книга для чтения. 4 класс. (4-й год). Пособие для учащихся общеобразовательных организаций и школ с углубленным изучением английского языка

Содержание

Стас Афанасьев. Juno. Pipelines на базе io.Reader/io.Writer. Часть 2 / Хабр

В докладе поговорим про концепцию io.Reader/io.Writer, для чего они нужны, как их правильно реализовывать и какие в связи с этим существуют подводные камни, а также про построение pipelines на базе стандартных и кастомных реализаций io.Reader/io.Writer.

Стас Афанасьев. Juno. Pipelines на базе io.Reader/io.Writer. Часть 1

Баг «на доверии»

Ещё один нюанс: в этой реализации есть «багуля». Этот баг подтверждён разработчиками (я им об этом написал). Может, кто-то знает, что это за «багуля»? Она на слайде – это предпоследняя строка:

Она связана со слишком большим доверием обёрнутому Reader’у: если Reader возвращает отрицательное количество байт, то лимит, который мы хотели бы получить по количеству вычитанных байт, увеличивается. И в некоторых случаях это довольно серьёзный баг, который сходу не понять.

Я написал в issue: давайте что-нибудь делать, давайте поправим! И тут вскрылся пласт проблем… Во-первых, мне сказали, что если добавить эту проверку сейчас сюда, эту проверку придётся добавить везде, а этих мест десяток. Если мы хотим это переложить на сторону клиента, то нужно определить ряд правил, по которым клиент будет валидировать данные (а их тоже может быть пяток-другой). Получается, всё это нужно скопировать.

Согласен, что это не оптимально. Тогда давайте придём к какому-нибудь консистентному варианту! Почему у нас одна реализация стандартной библиотеки не доверяет ничему, а другие доверяют абсолютно всему?

В общем, пока я писал своё гражданское мнение, обдумывал его, мы закрыли issue с комментариями – «Мы ничего делать не будем. До свидания»! Меня выставили каким-то дурачком… Вежливо, конечно, не придерёшься.

В общем, мы сейчас имеем проблему. Она заключается в том, что не понятно, кто должен валидировать данные завёрнутого Reader’а. То ли клиент, то ли мы всецело доверяем контракту… Есть у нас одно решение! Если останется время, я о нём расскажу.

Давайте переходить к следующему кейсу.

TeeReader

Мы рассмотрели пример, как оборачивать данные Reader’а. Следующий пример пайпов – это данные Reader перегнать в Writer. Тут имеют место две ситуации.

Первая ситуация. Нам нужно вычитывать данные из Reader’а, каким-то образом скопировать их в Writer (прозрачно) и работать с этим, как с Reader’ом. Для этого есть реализация TeeReader. Она представлена в верхнем сниппете реализации:

Работает подобно команде Tee в Unix’е. Думаю, многие из вас об этом слышали
Обратите внимание, эта реализация проверяет количество байт, которые она вычитывает из обёрнутого Reader’а. Видите условия во второй строке? Потому что, когда пишешь такую реализацию, интуитивно понятно: в случае прихода отрицательного числа ты получишь panic. И это ещё одно место, где мы доверяем обёрнутому Reader’у! Напоминаю, всё это стандартные библиотеки.

Давайте перейдём к кейсу, к примеру того, как это использовать. Что мы будем делать на нижнем сниппете? Будем скачивать файл robot.txt скачивать с сайта golang.org при помощи стандартного http-клиента.

Как известно, http-клиент возвращает нам структуру response, у которой поле Body является реализацией интерфейса Reader. Следует уточнить, сказав, что это реализация интерфейса ReadCloser. Но ReadCloser – это всего лишь интерфейс, собранный из Reader и Closer. То есть это Reader, который можно, в общем-то, закрыть.

На этом примере (на нижнем сниппете) мы собираем TeeReader, который будет вычитывать данные из этого Body и записывать их в файл. Создание файла сегодня, к сожалению, осталось за кулисами, потому что всё не помещалось. Но, опять-таки, если вы посмотрите дендрограмму, тип file реализует интерфейс Writer, то есть в него можем писать. Это очевидно.

Собрали наш TeeReader и вычитываем при помощи ReadAll. Всё работает, как и ожидалось: мы вычитываем получаемые Body, записываем его в файл и видим его в Assad out.

Beginner way

Вторая ситуация.

Нам нужно просто вычитать данные из Reader и записать их в Writer. Решение очевидно…

Когда я только начинал работать с Go, такие задачи решал, как на слайде:

Я лоцировал буфер, заполнял его данными из Reader’а и заполненный slice передавал в Writer. Всё просто.

Два момента. Во-первых, нет никакой гарантии, что за один вызов метода Read будет вычитан весь Reader, потому что там могут остаться данные (по-хорошему, это нужно делать в цикле).

Второй момент – это то, что данный путь не является оптимальным. Тут довольно шаблонный код, который написан до нас.

Для этого существует специальное семейство хелперов в стандартной библиотеке – это Copy, CopyN и CopyBuffer.

io.Copy. WriterTo и ReaderFrom

io.Copy в принципе делает то, что было на предыдущем слайде: он аллоцирует буфер по дефолту в 32 Кб и пишет данные из Reader в Writer (сигнатура этого Copy представлена на верхнем сниппете):

Помимо этого, помимо этой шаблонной рутины, он ещё содержит ряд хитрых оптимизаций.

И прежде чем мы про эти оптимизации поговорим, нам нужно познакомиться ещё с двумя интерфейсами:

  • WriterTo;
  • ReadFrom.

Гипотетическая ситуация. Ваш Reader работает с буфером памяти. Он уже его прелоцировал, пишет, что-то вычитывает оттуда, то есть место под него уже прелоцировано. Вы хотите этот Reader вычитать где-то извне.

Мы уже посмотрели, как это происходит: создаётся, алоцируется буфер, который передаётся в метод Read; Reader, который работает с памятью, уже из прелоцированного кусочка перекидывает… Но это уже не оптимально – место прелоцировано. Зачем делать ещё раз?

Где-то 5-6 лет назад (есть ссылка на change list) сделали два интерфейса: WriteTo и ReadFrom, которые реализуются по месту. Reader реализует WriteTo, а Writer – ReadFrom. Получается, Reader, имея уже прелоцированный slice с данными, может избежать дополнительной локации и принять методы Write To Writer и передать доступный внутри буфер.

Так работает реализация bytes.Buffer и bufio. И если вы в очередной раз посмотрите на дендрограмму, то увидите, что эти два интерфейса не очень-то популярны. Они как раз реализованы у тех типов, которые работают с внутренним буфером – там, где память уже прелоцирована. Это не поможет вам избежать элокации всякий раз, а только в том случае, когда вы уже работаете с прелоцированным куском.

ReaderFrom работает сходным образом (только он реализуется у Writer’а). ReaderFrom вычитывает весь Reader, который приходит ему аргументом (до EOF’а) и пишет куда-то во внутреннюю реализацию Writer’а.

Реализация CopyBuffer

На этом сниппете представлена реализация хелпера copyBuffer. Этот не экспортируемый copyBuffer используется под капотом у io.Copy, CopyN и CopyBuffer.

И здесь имеется небольшой нюанс, о котором стоит сказать. CopyN был недавно оптимизирован – отвязан от этой логики. Это как раз та оптимизация, о которой я говорил ранее: прежде чем создать дополнительный буфер в 32 Кб, происходит проверка – может, источник данных реализует интерфейс WriterTo, и этот дополнительный буфер не нужен?

Если этого не происходит, мы проверяем: а может, Writer реализует ReaderFrom, чтобы их соединить без этого посредника? Если и этого не происходит, остаётся последняя надежда: может быть, нам передали какой-то прелоцированный буфер, который мы могли бы использовать?

Так примерно и работает io. Copy.

Есть одна issue, которая полу-proposal, полубаг – непонятно что. Она висит уже полтора года. Звучит она так: CopyBuffer семантически неправильный.

К сожалению, здесь нет сигнатуры этого copyBuffer’а, но она выглядит точно так же, как этот не экспортируемый метод.

Когда вы вызываете copyBuffer в надежде избежать дополнительной локации, передаёте туда какой-то прелоцированный slice byte, работает следующая логика: если у Reader или Writer реализованы интерфейсы WriterTo и ReaderFrom, то нет никакой гарантии, что вам удастся избежать этой локации. Это приняли как proposal и обещали подумать об этом в Go 2.0. Пока это просто нужно знать.

Работа с io.Pipe. PipeReader и pipeWriter

Ещё один кейс: вам нужно данные из Writer’а каким-то образом получить в Reader’е. Довольно жизненный кейс.

Представьте, что у вас уже есть какие-то данные, они реализуют интерфейс Reader – всё с этим понятно. У вас есть потребность эти данные сжать, «позипать» и отправить в S3. В чём нюанс?..
Кто работал с типом gzip в пакете compess, знает, что сам gzip’ер – всего лишь прокси: он принимает в себя данные, реализует интерфейс Writer, он эти данные впишет, что-то с ними сделает, а затем должен куда-то их сбросить. На конструкторе он принимает реализацию интерфейса Writer.

Соответственно, здесь нам нужен какой-то промежуточный Writer, куда мы закинем уже сжатые данные, которые архивированы на первом этапе. Следующий наш ход – залить эти данные на S3. И стандартный клиент AWS’а принимает в качестве источника данных реализацию интерфейса io.Reader.

На слайде представлен pipeline – показано, как это выглядит: нам нужно перегнать данные перегнать из Reader в Writer, из Writer – в Reader. Как это сделать?

В стандартной библиотеке есть прикольная функция – io.Pipe. Она возвращает два значения: pipeReader и pipeWriter. Эта пара неразрывно связана. Представьте себе «детский телефон» на стаканчиках с верёвками: нет смысла говорить в один стаканчик, пока на другом конце никто не слушает…

Что делает этот io. Pipe? Он не будет вычитывать, пока данные никто не пишет. И наоборот, он не будет ничего писать, пока на другом конце эти данные никто не читает. Вот пример реализации:

Мы здесь будем делать то же самое. Будем вычитывать файл robot.txt, который вычитывали до этого, будем его сжимать при помощи нашего gzip и отправлять в S3.

  • На первой строке создаётся пара – pipeReader, pipeWriter. Далее мы должны запустить как минимум одну горутину, которая будет вычитывать данные с одного конца (своего рода труба). В этой горутине запускаем uploader с источником данных (источник – pipeReader).
  • На следующем этапе нам нужно сжать данные. Данные сжимаем и пишем в pipeWriter (он будет другим концом трубы), а уже запущенная горутина получает данные на другом конце трубы и вычитывает их. Когда весь этот бутерброд готов, остаётся только поджечь фитилёк…
  • Смотрите: io.Copy на последней строке пишет данные из Body в созданный нами gzip’ер (т. е. из Reader’а в Writer). Всё это отрабатывает так, как и ожидалось.

Этот пример можно решить и по-другому. Если вы используете какую-нибудь реализацию, которая реализует и Reader, и Writer. Вы будете в неё сначала записывать данные, а потом вычитывать их.
Это было наглядная демонстрация того, как работать с io.Pipe.

Другие реализации

На этом у меня в принципе всё. Мы подходим к интересным реализациям, о которых я хотел бы поговорить.

Я ничего не сказал ни про MultiReader, ни про MultiWriter. А это ещё одни прикольные реализации стандартной библиотеки, которые позволяют соединять различные реализации. Например, MultiWriter пишет одновременно во все Writer’ы, а MultiReader – вычитывает Reader’ы последовательно.

Ещё одна реализация называется limio. Она позволяет задать лимитирование для вычитывания. Можно задать скорость в байтах в секунду, с которой нужно вычитывать ваш Reader.

Ещё одна интересная реализация – это просто визуализация прогресса чтения – Progress bar (от какого-то чувака). Называется ioprogress.

Зачем я всё это говорил? Что я хотел этим сказать?

  • Если вам вдруг необходимо реализовывать интерфейсы Reader и Writer, делайте это правильно. Нет пока единого решения, кто отвечает за реализацию – будем считать, что все доверяют контракту. Значит, вам нужно безукоризненно его соблюдать.
  • Если ваш случай – это работа с прелоцированным буфером, не забывайте про интерфейсы ReaderFrom и WriterTo.
  • Если вы попали в тупик и вам нужны примеры – смотрите стандартную библиотеку, там много классных реализаций, на которые можно опираться. Там есть документация.
  • Если же вам что-то совсем непонятно, то не стесняйтесь писать issues. Ребята там адекватные, отвечают быстро, очень вежливо и грамотно вам помогут.

На этом у меня всё. Спасибо, что пришли!

Вопросы

Вопрос из аудитории (В): – У меня вопрос простой, наверное. Расскажи, пожалуйста, о каких-нибудь use-кейсах из жизни: какие использовались и зачем? Ты говорил, что Reader / Writer возвращает длину, которую он прочитал. Были ли у тебя в практике случаи, когда с этим возникали проблемы; когда ты требовал прочитать (не просто ReadAll существует), а что-то не получалось?

СА: – Надо честно признаться, у меня таких кейсов никогда не возникало, потому что я всегда работал с реализациями стандартной библиотеки. Но гипотетически такая ситуация, конечно, возможно. Что касается конкретных кейсов, то мы частенько собираем многослойные пайпы, и если гипотетически допустить такой баг весь пайп развалится…

В: – Это не совсем баг. Давай тогда расскажу о своём небольшом опыте. У меня была проблема с компанией Booking.com: они использовали драйвер, который я написал, и у них была проблема – что-то не доходило. Есть стандартный бинарный протокол, который мы делали; локально всё хорошо работает, у всех всё хорошо, но оказалось, что у них очень плохая сеть с дата-центром. Тогда Reader действительно возвращал не всё (плохие сетевые карты, ещё что-то).

СА: – Но если он возвращал не всё, то он не должен был возвращать признак конца (окончания), и клиент должен был прийти ещё раз. По контракту, который описан, Reader не должен… Скажем так, Reader, конечно, сам решает, когда он хочет приходить, когда не хочет, однако, если он хочет вычитать всё, то должен ждать EOF’а.

В: – Но это именно из-за соединения. Именно такая проблема возникала в стандартном пакете net.

СА: – И он возвращал EOF?

В: – Он не всё возвращал – просто не всё вычитывал. Я ему говорю: «Прочитай следующие 20 байт». Он читает. И у меня вычитывает не всё.

СА: – Гипотетически это возможно, потому что это всего лишь интерфейс, который описывает протокол коммуникации. Надо смотреть и конкретно разбирать кейс. Здесь я вам могут только ответить, что клиент, по идее, должен был прийти ещё раз, если он не получил всё, что хотел. Вы просили у него slice из 20 байт, он вычитал вам 15, но не пришёл EOF – надо бы ещё раз сходить…

В: – Для такой ситуации есть io.ReadFull. Он специально создан, чтобы вычитывать слайс до конца.

СА: – Да. Про ReadFull я ничего не сказал.

В: – Это вполне нормальная ситуация, когда Read заполняет не весь slice. К этому нужно быть готовым.

СА: – Это вполне ожидаемый кейс!

В: – Спасибо за доклад – было интересно. Я использую Reader’ы в маленьком простеньком прокси, который читает http и пишет в другую сторону. Я использую Close Reader, чтобы решить одну проблему – всё время закрывать то, что прочитал. Нужно ли мне слепо доверять контракту? Вы говорили о том, что там могут быть проблемы. Или добавить дополнительные проверки? Теоретически возможно, что на этом участке что-то придёт не полностью. Нужно ли мне эти дополнительные проверки делать и не верить контракту?

СА: – Я бы так сказал: если ваше приложение терпимо к этим ошибкам (например, если вы всецело доверяете контракту), то, возможно, нет. Но если вы не хотели бы получить у себя «панику» (как я показывал на негативном чтении в byte.Buffer), то я бы всё-таки проверял.
Но это – “up to you”. Что я могу вам порекомендовать? Думаю, просто взвесьте все за и против. Что будет, если вдруг вы получите отрицательное количество байт?

В: – Спасибо за доклад. К сожалению, я в Go ничего не знаю. Если «паника» произошла, есть ли какой-то способ это перехватить и вывести информацию о том, что, где, как и задебажить, чтобы в пятницу вечером избежать проблем?

СА: – Есть. Механизм Recover позволяет «панику» выловить и вывести её, не падая, условно говоря.

В: – Как ваши рекомендации по использованию реализаций Writer и Reader согласуются с ошибками, которые возвращаются при реализации веб-сокетов. Конкретный пример не приведу, но всегда ли там end of file используется? Насколько я помню, сообщение завершается какими-то другими значениями…

СА: – Вопрос хороший, потому что мне просто нечего на него ответить. Надо смотреть! Если не приходит EOF, то клиент, если хочет всё получить, должен ходить ещё раз.

В: – Насколько длинный pipe получалось собрать? Есть ли какие-то внутренние убеждения, что пайп больше пяти участников собирать не стоит, или с ветвлениями? Насколько длинное дерево получилось выстроить из этих пайпов (Read, Write)?

СА: – На моей практике примерно пять последовательных call’ов – это оптимально, потому что дальше сложнее дебажить, держать в голове, что и куда вытекает. Довольно ветвистая структура получается. Но я бы сказал где-то 5-7 максимум.

В: – 5-7 – это в каком кейсе?

СА: – Это чтение, например, каких-то данных. Вам нужно залогировать, причём то, что вы логируете, нужно обрезать. Залогировали – дальше вы эти данные вычитали – вам нужно отправить это ещё в какой-тол storage (ну, гипотетически). В любой storage, которые реализует интерфейс Writer. При таком пайпе 5-6 шагов происходит, притом что на одном из шагов он ещё ветвится куда-то в сторону, а вы продолжаете работать с Reader’ом.

В: – По Beginner way у вас был интересный слайд. Можете указать ещё 2-3 интересных момента, которые были, но сейчас их точно лучше не делать, а делать теперь по-другому?

СА: – Тем слайдом я хотел показать именно то, как делать не нужно касаемо вычитывания Reader’а. Сходу в голову мне ничего не приходит что-то вроде Beginner way… Это, наверное, основная ошибка, основной паттерн, которого следует избегать при работе с Reader’ами.
Ведущий: – Я бы добавил от себя, что начинающему очень важно прочитать всю документацию пакета io, на все интерфейсы, которые там есть, и понять их. Потому что на самом деле их там очень много, а вы часто начинаете делать что-то своё, хотя там это уже есть и правильно реализовано («правильно» – с учётом всех особенностей).
Вопрос ведущего: – Как дальше жить-то?

СА: – Хороший вопрос! Я обещал рассказать, если у нас останется время. По итогу обсуждения бага в LimitedReader появилось такое решение: сделать в некотором смысле Reader-«презерватив», который защищает от внешних угроз, оборачивает какой-то Reader, которому вы не доверяете – не пускать всякую заразу внутрь своей системы.

И в этом Reader’е вы реализуете все проверки, которые «нельзя» делать: например, негативное чтение, эксперименты с количеством байт (скажем, вы послали slice из 10 байтов, а вам вернулось 15 – как на это реагировать?)… В этом Reader’е и можно реализовать набор таких проверок. Я сказал: «Может, давайте добавим в стандартную библиотеку, потому что это было бы полезно использовать всем»?

Мне был дан ответ, что смысла в этом вроде как нет – это простая штука, которую можно реализовать самостоятельно. Всё. Живём дальше. Доверяем контракту, ребята. Но я бы не доверял.

В: – Когда мы работаем с Reader’ами, Writer’ами и есть возможность нарваться на gzip-«бомбу»… Насколько мы доверяем потоком ReadAll и WriteAll? Или всё-таки реализовать буферное чтение и работать только с буфером?

СА: – Сам ReadAll использует под капотом всего лишь bytes.Buffer. Когда вы хотите использовать ту или иную штуку, вам желательно влезть и посмотреть, как эти «кишочки» реализованы. Опять же, зависит от ваших требований: если вы нетерпимы к таким ошибкам, которые я показал, нужно посмотреть, проверяется ли то, что приходит из обёрнутого Reader’а. Если не проверяется – использовать, например, bufio (там всё это проверяется). Либо делать то, что я сейчас рассказал: некий прокси-Reader, который будет по вашему списку требований проверять эти данные и – либо возвращать их клиенту, либо возвращать клиенту.


Немного рекламы 🙂

Спасибо, что остаётесь с нами. Вам нравятся наши статьи? Хотите видеть больше интересных материалов? Поддержите нас, оформив заказ или порекомендовав знакомым, облачные VPS для разработчиков от $4.99, уникальный аналог entry-level серверов, который был придуман нами для Вас:Вся правда о VPS (KVM) E5-2697 v3 (6 Cores) 10GB DDR4 480GB SSD 1Gbps от $19 или как правильно делить сервер? (доступны варианты с RAID1 и RAID10, до 24 ядер и до 40GB DDR4).

Dell R730xd в 2 раза дешевле в дата-центре Equinix Tier IV в Амстердаме? Только у нас 2 х Intel TetraDeca-Core Xeon 2x E5-2697v3 2.6GHz 14C 64GB DDR4 4x960GB SSD 1Gbps 100 ТВ от $199 в Нидерландах! Dell R420 — 2x E5-2430 2.2Ghz 6C 128GB DDR3 2x960GB SSD 1Gbps 100TB — от $99! Читайте о том Как построить инфраструктуру корп. класса c применением серверов Dell R730xd Е5-2650 v4 стоимостью 9000 евро за копейки?

Книга Брак по расчету.

Я развожусь! , глава Пролог, страница 1 читать онлайн

Брак по расчету. Я развожусь!

Ты что, думала я влюбился в тебя по уши? Серьезно? Да ты мне даром не сдалась! — обжигает словами Дима.
— Прости, что? — не верю в услышанное. — Ты вообще-то умолял, чтобы я за тебя замуж вышла! А сейчас что?! У тебя каждый день новая баба! Ты абсолютно наплевал на меня и мои чувства! На то, что мы в браке. И что я твоя жена…
— Верно, Милена. Ты совсем не в моем вкусе. Это было решение моей семьи. Несколько месяцев, в потом разводимся. Ясно тебе?!

Ясно, конечно. Развод обязательно будет. Да только тогда ты, милый, будешь ползти на коленях. Чтобы я не уходила от тебя.


Безобразие. Хрен недоделанный с пустой головой. С двумя головами! Но они обе ни о чем! Которая на плечах — вообще тупая. А которая в штанах — агррр… Как же я злюсь!

Димочка Сергеевич, где же ты у меня шляешься, что все ещё домой не вернулся? А ведь я тебя прикончу собственными руками! Засуну в стиральную машину (ну уж постараюсь тебя туда впихнуть), и включу барабан. Чтобы ты отрезвился. И понял, что от меня не сбежать.

Нет, все же ждать я не могу. Быстренько сибираюсь, а точнее забираю мобильник и ключи от автомобиля и выбегаю во двор.

Ехать минут пятнадцать. Если нажать на педаль газа по полной программе, то можно и за семь минут. Это я примерно, если что. Пару раз так мчалась в офис мужа, но время не засекала.

Мобильный вибрирует и я беру трубку, не всматриваясь в экран:

— Да, — рычу.

— Эй, полегче. Ты на что-то снова разозлилась? — спрашивает сестра и затаив дыхание ждёт от меня ответа. — Что у тебя с настроением?

— Да ниче, Алиночка Тимуровна. Все круто у меня. Щас я за рулём и говорить особо не могу, но я обязательно перезвоню тебе через минут двадцать и сообщу очень хорошую новость. А может и видео отправлю, чтобы ты не задавалась вопросами. Коротко и ясно. Зато все понятно. Договорились?

— Милен, — зовёт меня сестра после короткой паузы. — Ты случайно…

— Ой, нет, Алиночка моя Тимуровна. Я трезвая и сейчас мне хочется стукнуть своего мужа по голове и желательно чем-нибудь очень и очень тяжёлым! Поможешь?! — последнее предложение цежу сквозь зубы.

— Так, ясно с тобой все. Через полчаса буду у тебя. Нужно успокоить Милену Тимуровну, а то она там от чего-то с ума сходит. Саш, ты же присмотришь за дочкой?

—… Куда это ты на ночь глядя? — доносится строгий голос мужа сестры. — Нет, Алин. Поедешь только со мной.

— Так стоп. Алин, поставь-ка ты на громкую связь.

— Поставила она. Если ты хочешь меня подколоть, Миленочка Тимуровна, то я готов. Жги! — язвит Саша.

— Не буду я подкалывать! Да и вообще не до тебя мне. Но твоя помощь понадобится, да. Скажи, у тебя случайно нет дома секатора? Мне очень надо.

Воцаряется тишина. А потом кашель, явно Сашин.

— Блин, Милен, он поперхнулся чаем.

— Нечего жрать на ночь глядя! — ворчу недовольно. — Мне, говорю, секатор нужен!

— Зачем? — наконец подаёт голос Саша.

— Чтобы ему одно место с корня отрезать! — повышаю я голос. — Чтобы не бегал по другим бабам! Чтобы у него никогда в жизни больше не вставало! Вот же… Гад!

— Так, я не понял. Дима изменяет тебе, что ли? Ну вообще-то я тебе изначально говорил, что он тебе не пара, — умничает Сашенька Рамилевич.

— Знаешь, Санёк, я обязательно куплю два секатора и один из них дам сестре. Хорошо, Алиночка? И пользоваться им научу. Это на всякий пожарный. Чтобы твой любимый меженок налево не смотрел.

— Договорились, сестрёнка! — смеётся Алина.

— Ты мне тут не капай на мозги жены. Лучше скажи, нам приезжать? Или ты хочешь отрезать ему… Кхм… Наедине? Чтобы свидетелей не было и никто потом против тебя показания не давал…

— Я вам перезвоню, — обещаю, останавливая машину неподалеку от компании и решаю дальше идти пешком.

Нужно постараться чуточку успокоится, выветрить голову (она у меня гениальная, в отличии от Диминого), потому что я уже сто раз представила перед глазами ту картину, где мой муж лапает другую. А я выгоняю ту бабу, растегиваю ремень и тяну его брюки вниз, приступаю к делу. То есть… Отрезаю ему антену!

— Добрый вечер, — встречает меня милая девушка у лифта, кажется, с ресепшена. — Вы к кому?

— К Димочке Сергеевичу Беркутову. Надеюсь, он не сильно занят? В такое время… — кошусь на наручные часы.

— Вы же Милена? Та самая модель, которая…

— Да-да. Которая недавно была на первых страницах нескольких журналов. Но сейчас мне нужно подняться к Дмитрию, нет времени на болтовню. Вы же не станете меня останавливать?

Тон насмешливый. Она должна понять, что я злая и еле держу свои эмоции под контролем. Скоро взорвусь. Я его жена, черт возьми, но жду от какой-то бабы добра, чтобы подняться к нему!

— Конечно же не буду. Проходите. Вы же его жена.

Жена, мать вашу! Жена! И до нее это только сейчас дошло?! После расспроса?

— Не нужно проводить. Спасибо, — выдавливаю из себя. Интересно, что эта баба делает тут? В такое время… Кхм… Надо узнать у Сергея Владиславовича. Димон уж точно не ответит.

Останавливаюсь у двери кабинета и слышу голоса.

Женский… Мужской… Первый, конечно же, не узнаю. Но вот голосок Димочки Сергеевича я не спутаю ни с чьим. Кхм.. а зря ты так, муженька… Очень зря.

Не буду же я сбегать, как это делают бабы в сериалах. Мне нужно увидеть предателя. Убедиться который раз, что там в кабинете не включен фильм, а стоят двое обнаженных людей и шушукаются между собой. Трогают заветные места друг друга.

Я конечно же открываю дверь и захожу. И да, вижу мужа с красивой шатенкой. Они стоят перед ним, он же на диване расположился. Хозяин же, черт его дери! Она в нижнем белье, а мой муж в одежде, к моему удивлению. А, ещё… Красотка стоит перед ним на коленях. Интересно…

Громадское Радио: Интервью «Украина зовет» Геннадий Афанасьев — 06 марта 2017

Вы читаете: Громадское Радио: Интервью «Украина зовет» Геннадий Афанасьев

Война России против Украины

Автор Громадское .

На этой недатированной фотографии изображен Геннадий Афанасьев. Он был выпускником юридического факультета и работал фотографом, когда его задержала полиция в Крыму, который к тому времени находился под властью России. И посадили. Два года провел в российских тюрьмах. После освобождения в рамках обмена пленными он был активистом общественной жизни и работал советником в Министерстве иностранных дел [Украины], помогая другим украинским политзаключенным.

Фото Twitter

Примечание редактора: Ниже приводится англоязычная стенограмма программы Громадське Радио «Украина зовет» от 3 марта, в которой берет интервью Геннадий Афанасьев. Афанасьев был выпускником юридического факультета и работал фотографом, когда его задержала полиция в Крыму, который к тому времени находился под властью России. И посадили. Ему удалось пережить два года пыток в российских тюрьмах. После освобождения в рамках обмена пленными он был активистом общественной жизни и работал советником в Министерстве иностранных дел [Украины], помогая другим украинским политзаключенным.

Привет и добро пожаловать в Ukraine Calling, ваш еженедельный обзор того, что происходит в Украине, с акцентом на основной вопрос. Меня зовут Оксана Смеречук, я работаю на Громадском радио в Киеве, и вот несколько историй, которые были в новостях на этой неделе.

Подробнее здесь.

Подробнее в этом разделе

Все, что вам нужно знать о Дне памяти жертв Голодомора

Москва продолжит бомбить Украину – Посол России в ООН

Новая мемориальная доска в честь Гарета Джонса из Уэльса

Лондонский митинг требует больше оружия для границы Украины Зеленского

Защитник животных в охваченной войной Украине получил международную награду

На конференции Лейбористской партии Великобритании призывают к большему количеству оружия и поддержке Зеленского в Украине  

Биограф украинского голодомора Признает храбрость

ЧИТАЙТЕ: последний ежедневный адрес Зеленского

X

Уважаемый читатель,
Это дружеское напоминание о том, что при посещении Kyiv Post следует отключать блокировщик рекламы.
Мы уважаем и понимаем ваш выбор избегать рекламы, но большинство блокировщиков рекламы также предотвращают полную загрузку страниц,
остановить работу нашего сайта на полную мощность и заблокировать вход в систему, функции регистрации и многое другое.
Пожалуйста, отключите программное обеспечение для блокировки рекламы или добавьте наш сайт в белый список, чтобы использовать его в полном объеме.

С любовью, команда Kyiv Post

Афанасьев П. | Semantic Scholar

Следовать за автором…

Заявка на страницу автора

Страницы авторов создаются на основе данных, полученных от наших академических партнерств с издателями и из общедоступных источников.

Сортировка по наиболее влиятельным статьям Сортировка по количеству цитирований Сортировка по давности

Гидродеоксигенирование гваякола с CoMo катализаторами. Часть I. Промотирующее действие кобальта на селективность и активность HDO

  • В. Н. Буй, Д. Лауренти, П. Афанасьев, К. Жанте
  • Химия

  • 14 января 2011 г.

tab)

Граничная смазка: влияние размера и структуры неорганических фуллереноподобных наночастиц MoS2 на снижение трения и износа

  • P. Rabaso, F. Ville, T. Mogne
  • Материаловедение

  • 15 декабря 2014 г.

Просмотр через Publisher (открывается в новой вкладке)

Обзор эффектов поддержки в катализаторах гидроочистки Вринат

  • Химия

  • 1 ноября 2003
  • Просмотр через Publisher (откроется в новой вкладке)

    Синтетические подходы к сульфидмолибденовым материалам

    • . Афанасьев0105

      Химия, материаловедение

    • 23 июня 2009

    Просмотр через Publisher (opens in a new tab)

    Влияние восстановительных и сульфидирующих условий на свойства ненанесенных катализаторов на основе MoS2

  • Афаниев П.
  • Химия

  • 5 февраля 2010 г.
  • Просмотр через Publisher (opens in a new tab)

    Высоковалентный дижелезо-оксосодержащий N-мост на платформе порфирина, способный окислять метан.

    • Кудрик Е.В., Афанасьев П., Сорокин А.
    • Химия, биология

      Природа Химия

    • 1 декабря 2012 г. Сообщается о катион-радикалах O-тетрафенилпорфирина при -90 ° C, характеризуемых ультрафиолетовой и видимой, электронным парамагнитным резонансом и мессбауэровской спектроскопией, а также масс-спектрометрией с ионизацией электрораспылением, которая проявляет очень высокую активность в отношении переноса атома кислорода на алканы, включая метан.

      Просмотр в PubMed (откроется в новой вкладке)

      Недавние исследования по приготовлению, активации и дизайну активных фаз и носителей катализаторов гидроочистки M. Vrinat

    • Chemistry

    • 15 January 2008

    View via Publisher (opens in a new tab)

    Molten salt synthesis of barium molybdate and tungstate microcrystals

    • P. Afanasiev
    • Химия, материаловедение

    • 1 сентября 2007 г.

    Просмотр через Publisher (opens in a new tab)

    Синтез растворов Co(Ni)–Mo–S катализаторов гидроочистки без носителя

  • , P. Genuit 901it Афанасьев, М. Вринат
  • Химия

  • 25 октября 2005 г.
  • Просмотр через Publisher (opens in a new tab)

    Новый маршрут из одного источника к нитриду молибдена Mo(2)N.

    • П. Афанасьева
    • Материаловедение

      Неорганическая химия

    • 14 октября 2002 г.

    Дисперсный Mo(2)N с пластинчатой ​​морфологией и высокой удельной поверхностью получен разложением (HMT)(2)(NH(4) )(4)Mo(7)O(24) соль в интервале температур 550-800 градусов С.

    Посмотреть в PubMed (откроется в новой вкладке)

    Авторы в той же области или соавторы, рекомендованные нашей системой на основе данных цитирования

    • C.

    Добавить комментарий