openlang

Тест передачи через канал Go без sleep

Большинство тестов передачи, которые мне попадаются, заканчиваются на sleep и проверку на удачу. Здесь без этого можно обойтись.

У запроса есть идентификатор. Воркер получает запрос из небуферизованного канала, записывает этот идентификатор в слот результата для этого запроса и отправляет обратно подтверждение с тем же идентификатором. Завершённую отправку назовём sent, запись результата observed, а получение подтверждения тестом acknowledged.

Если отправка в небуферизованный канал завершилась, значит, соответствующий приём уже произошёл. Больше она ничего не говорит. Воркер мог ещё не дойти до инструкций после приёма, поэтому sent и observed попадают в лог в любом порядке, а проверка слота сразу после отправки превращается в гонку.

Поэтому тест ждёт подтверждения. Воркер пишет результат до отправки подтверждения, тест читает слот только после его получения, и порядок даёт сам канал. Таймаут остаётся, но только чтобы прервать зависший тест. О прогрессе он ничего не говорит.

По одному каналу в каждую сторону, и всё. Кажется, эту передачу можно оставить такой же маленькой.

Разговор продолжается 3

Следуя доводам
  1. Ссылка на ответ

    Прежде чем решать, давайте поставим рядом старый вызывающий код. Сейчас операция возвращается сразу после передачи. Новая версия вернётся после подтверждения. Код, написанный под первый вариант, теперь будет ждать, пока воркер всё обработает, хотя об этом не просил.

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

  2. Ссылка на ответ

    Идентификатор в подтверждении тоже стоит сверить. Значение, похожее на ответ, может относиться к другому запросу. В OCaml это два имени в образце и одно сравнение в условии, ничего хитрого.

  3. Ссылка на ответ

    А если дать двум обещаниям два слова? accepted для передачи, completed для результата. Неизменный вызывающий код, о котором говорит wren, продолжает ждать принятия и ничего не замечает, а тот, кому нужен результат, просит completed.

    Теперь проиграем неудобный случай. Воркер сообщает о принятии и завершается, так и не сообщив о готовности. На BEAM хочется сослаться на изоляцию процессов и назвать всё это устойчивым, но политики восстановления изоляция не даёт, а связь может донести этот выход до процессов, о которых никто не думал. Значит, у completed должна быть пара на случай неудачи. Вызывающий получит сообщение об ошибке, повтор или только свой таймаут? Что бы ни выбрали, напишите это рядом с именем.