Перейти на неблокирующую отправку канала, проверить на наличие отказа перед попыткой отправки?

Есть ли способ проверить сбой отправки канала go без фактической попытки отправки? Стандартная неблокирующая отправка выглядит так:

msg := "hi"
select {
    case messages <- msg:
        fmt.Println("sent message", msg)
    default:
        fmt.Println("no message sent")
    }

Проблема в том, что мне нужно, чтобы "msg" был готов к отправке, чтобы проверить канал.

Я хотел бы проверить, не произойдет ли отправка с ошибкой, не требующей готовности «msg» для отправки.


person Ian Steep    schedule 12.03.2015    source источник
comment
Отправка будет буферизована, заблокирована, истечена по тайм-ауту или выполнена. Как говорит JimB: это гонка данных, чтобы предположить, что вас не заблокируют. Если вы не думаете, что отправитель находится в правильном состоянии для отправки или получатель в правильном состоянии для получения, то это просто проблема с дизайном протокола. Вы можете получать обновления состояния от клиента о том, считает ли он, что примет отправку.   -  person Rob    schedule 12.03.2015
comment
Итак, ответ — нет. Для этого нет встроенного механизма. Спасибо за проверку.   -  person Ian Steep    schedule 16.03.2015
comment
С той оговоркой, что если вы сделаете буфер достаточно большим и сумеете никогда не заполнить его, вы никогда не столкнетесь с блокировкой на практике. Никогда не заполнять буфер требует, чтобы сообщения всегда потреблялись своевременно; что гарантируется только в том случае, если отправитель прекращает отправку до заполнения буфера. Если подумать, то это похоже на блокировку отправителя (отказ от отправки), потому что он знает, что получатель заполнен.   -  person Rob    schedule 16.03.2015


Ответы (1)


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

Если вам нужен этот шаблон, вам нужен либо второй канал для сигнализации,

select {
    case <-ready:
        msg := generateMsg()
        messages <- msg
        fmt.Println("sent message", msg)
    default:
        fmt.Println("no message sent")
}

или вы можете использовать sync.Cond

person JimB    schedule 12.03.2015