Allenxuxu / gev

🚀Gev is a lightweight, fast non-blocking TCP network library / websocket server based on Reactor mode. Support custom protocols to quickly and easily build high-performance servers.
MIT License
1.72k stars 193 forks source link

关闭连接时,为什么不直接关闭连接,而是将【关闭连接】这个任务放到异步队列里面等待执行? #125

Closed Choubeihai closed 2 years ago

Choubeihai commented 2 years ago
  // Close 关闭连接
func (c *Connection) Close() error {
    if !c.connected.Get() {
        return ErrConnectionClosed
    }

    c.loop.QueueInLoop(func() {
        c.handleClose(c.fd)
    })
    return nil
}

关闭连接时,为什么不直接关闭连接,而是将【关闭连接】这个任务放到异步队列里面等待执行?

Choubeihai commented 2 years ago
   // Send 用来在非 loop 协程发送
func (c *Connection) Send(data interface{}, opts ...ConnectionOption) error {
    if !c.connected.Get() {
        return ErrConnectionClosed
    }

    opt := ConnectionOptions{}
    for _, o := range opts {
        o(&opt)
    }

    c.loop.QueueInLoop(func() {
        if c.connected.Get() {
            bytesAfterPackets := c.protocol.Packet(c, data)
            c.sendInLoop(bytesAfterPackets)

            if opt.sendInLoopFinish != nil {
                opt.sendInLoopFinish(data)
            }
        }
    })
    return nil
}

还有这个,Send这个API我理解是异步发送消息,触发的是eventfd,这个eventfd仍然是被epoll管理的,最终也是在epoll_wait中(gev里面的poll)中被触发,这不也是在eventloop协程中发送吗?但是您的注释是非loop协程发送。

Allenxuxu commented 2 years ago
// Close 关闭连接
func (c *Connection) Close() error {
  if !c.connected.Get() {
      return ErrConnectionClosed
  }

  c.loop.QueueInLoop(func() {
      c.handleClose(c.fd)
  })
  return nil
}

关闭连接时,为什么不直接关闭连接,而是将【关闭连接】这个任务放到异步队列里面等待执行?

为了线程安全

Allenxuxu commented 2 years ago
 // Send 用来在非 loop 协程发送
func (c *Connection) Send(data interface{}, opts ...ConnectionOption) error {
  if !c.connected.Get() {
      return ErrConnectionClosed
  }

  opt := ConnectionOptions{}
  for _, o := range opts {
      o(&opt)
  }

  c.loop.QueueInLoop(func() {
      if c.connected.Get() {
          bytesAfterPackets := c.protocol.Packet(c, data)
          c.sendInLoop(bytesAfterPackets)

          if opt.sendInLoopFinish != nil {
              opt.sendInLoopFinish(data)
          }
      }
  })
  return nil
}

还有这个,Send这个API我理解是异步发送消息,触发的是eventfd,这个eventfd仍然是被epoll管理的,最终也是在epoll_wait中(gev里面的poll)中被触发,这不也是在eventloop协程中发送吗?但是您的注释是非loop协程发送。

注释不太准确,意思是这个方法可以不在 loop 中执行