【问题标题】:The connection is closed before the keepAliveDurationNs is reached在达到 keepAliveDurationNs 之前关闭连接
【发布时间】:2021-07-20 19:45:55
【问题描述】:

在okhttp的代码中,connection.idleAtNs已经在releaseConnectionNoEvents()方法中赋值,

    internal fun releaseConnectionNoEvents(): Socket? {
        val connection = this.connection!!
        connection.assertThreadHoldsLock()
    
        val calls = connection.calls
        val index = calls.indexOfFirst { it.get() == this@RealCall }
        check(index != -1)
    
        calls.removeAt(index)
        this.connection = null
    
        if (calls.isEmpty()) {
          connection.idleAtNs = System.nanoTime()
          if (connectionPool.connectionBecameIdle(connection)) {
            return connection.socket()
          }
        }
    
        return null
      }

但为什么要在这里重新分配

        private fun pruneAndGetAllocationCount(connection: RealConnection, now: Long): Int {
        connection.assertThreadHoldsLock()
    
        val references = connection.calls
        var i = 0
        while (i < references.size) {
          val reference = references[i]
    
          if (reference.get() != null) {
            i++
            continue
          }
    
          // We've discovered a leaked call. This is an application bug.
          val callReference = reference as CallReference
          val message = "A connection to ${connection.route().address.url} was leaked. " +
              "Did you forget to close a response body?"
          Platform.get().logCloseableLeak(message, callReference.callStackTrace)
    
          references.removeAt(i)
          connection.noNewExchanges = true
    
          // If this was the last allocation, the connection is eligible for immediate eviction.
          if (references.isEmpty()) {
            connection.idleAtNs = now - keepAliveDurationNs
            return 0
          }
        }
    
        return references.size
      }

如果在这里赋值,可能会出现连接一空闲就被删除的样子。

【问题讨论】:

  • 请使用 ie 标签使您的帖子更具可读性。将您的文字与示例区分开来的帖子提供了视觉上的区别,并且可以更快地阅读和回答。很好地把你的问题提出来!
  • 好的,我已经修改了。

标签: okhttp


【解决方案1】:

pruneAndGetAllocationCount 方法作为清理任务的一部分被调用。在您链接到的地方,代码已经记录了有关连接泄漏的警告。代码释放该连接,然后认为该连接立即可供释放。

如果您对代码有疑虑,请考虑制作一个测试用例,显示您建议将代码更改为的内容,这样可能会对其进行改进。

如果由于连接泄漏而影响到您,您应该修复应用程序代码中的错误。

          // We've discovered a leaked call. This is an application bug.
          val callReference = reference as CallReference
          val message = "A connection to ${connection.route().address.url} was leaked. " +
              "Did you forget to close a response body?"

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-12-23
    • 2019-12-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多