Skip to content

Cancelling task or shutting down streaming server does not send client RST_STREAM anymore. #22

@ericdusel-tri

Description

@ericdusel-tri

I had code working on the following versions:

grpc-swift v2.1.1
grpc-swift-nio-transport v1.0.2
grpc-swift-protobuf v1.1.0

and I upgraded to:

grpc-swift-2 v2.1.0
grpc-swift-nio-transport v2.1.1
grpc-swift-protobuf v2.1.1

Before, when I cancelled the Task that the server is running in, I would get an error on the client side saying "Received RST_STREAM with error code 8" in python or "Stream unexpectedly closed: received RST_STREAM frame (0x8: cancel)" in swift.

Now when I cancel, I get no indication on the client that the stream has stopped.

I am not sure if this is intended behavior but it makes it difficult to troubleshoot if the server side has been shutdown or cancelled based on the status of the client.

My server definition looks like:

  func runServer() async throws {
      let features = try self.loadFeatures()
      let service = RouteGuideService(features: features)
    let server = GRPCServer(
      transport: HTTP2ServerTransport.Posix(
        address: .ipv4(host: "0.0.0.0", port: 12345),
        transportSecurity: .plaintext
      ),
      services: [service]
    )

          try await withTaskCancellationHandler {
              try await server.serve()
          } onCancel: {
              print("Shutting down")
              server.beginGracefulShutdown()
          }

      if let address = try await server.listeningAddress {
          print("Tracker server listening on \(address)")
      }
  }
    private func loadFeatures() throws -> [Routeguide_Feature] {
      guard let url = Bundle.main.url(forResource: "route_guide_db", withExtension: "json") else {
        throw RPCError(code: .internalError, message: "Couldn't find 'route_guide_db.json")
      }

      let data = try Data(contentsOf: url)
      return try Routeguide_Feature.array(fromJSONUTF8Bytes: data)
    }
struct RouteGuideService: Routeguide_RouteGuide.SimpleServiceProtocol {
    private let features: [Routeguide_Feature]
    /// - Parameter features: Known features.
    init(features: [Routeguide_Feature]) {
      self.features = features

    }

    func listFeatures(
      request: Routeguide_Rectangle,
      response: RPCWriter<Routeguide_Feature>,
      context: ServerContext
    ) async throws {
      let featuresWithinBounds = self.features.filter { feature in
        !feature.name.isEmpty && feature.isContained(by: request)
      }

      // try await response.write(contentsOf: featuresWithinBounds)
      for f in features {
        try await response.write(f)
        try await Task.sleep(nanoseconds: UInt64(2 * Double(NSEC_PER_SEC)))
      }
    }

}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions