Безопасное близкое соединение в Голанге

Когда я открываю сокетное соединение, я сразу же помещаю логику socket.Close() в функцию отсрочки после открытия сокета. Однако что, если socket.Close() вызовет новую панику? Должен ли я всегда вкладывать еще одну отсрочку/восстановление во внешнюю отсрочку, чтобы предотвратить сбой моей программы? Примерно так: http://play.golang.org/p/GnEMQS-0jj

Спасибо, Элгс.


person Qian Chen    schedule 10.12.2013    source источник
comment
socket.Close() не может вызвать панику IIRC.   -  person fuz    schedule 10.12.2013
comment
Я не совсем уверен: закрытие (например, на net.TCPConn) может привести к ошибке, но я думаю, что это не паника. И если он паникует, например. из-за повреждения оборудования или из-за нехватки памяти ваше приложение все равно будет сброшено. В зависимости от вашего случая вы можете захотеть обработать возвращенную ошибку, но обработка паники в Close кажется немного параноидальной.   -  person Volker    schedule 10.12.2013
comment
@FUZxxl, когда я пытаюсь закрыть клиентский сокет, которому сервер отказывается подключаться, он паникует. Есть ли способ определить, безопасно ли закрытие сокета без паники. Или мне нужно вложить еще один уровень отсрочки только для логики закрытия сокета.   -  person Qian Chen    schedule 24.12.2013
comment
@ElgsQianChen Это похоже на ошибку в Go. Сообщите об ошибке в системе отслеживания ошибок.   -  person fuz    schedule 24.12.2013


Ответы (1)


Как правило, вам не нужно сильно беспокоиться о панике. Обычно они представляют собой два класса ошибок: ошибки разработчика (нулевые ссылки, выход за границы массива) и ошибки системного уровня, с которыми вы, вероятно, мало что можете поделать (например, нехватка памяти).

Как говорили другие, socket.Close не будет паниковать, а вернет ошибку. Если вы сделаете:

defer socket.Close()

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

Но предположим, что вы действительно хотите оправиться от паники. Если ваш обработчик восстановления отложен первым, вам больше ничего не нужно делать:

func main() {
  defer func() {
    if err := recover(); err != nil {
      fmt.Println(err)
    }
  }()
  defer panic("this will be recovered")
}

Отложенные функции выполняются в обратном порядке: http://golang.org/ref/spec#Defer_statements.

Отложенные функции выполняются непосредственно перед возвратом из окружающей функции, в порядке, обратном их отложенному выполнению.

person Caleb    schedule 10.12.2013