Question about whenSuccess in EventLoopFuture

Hi,

I have the following code, which

  1. remove a handler in channel pipeline
  2. add a new handler in the same pipleline
  3. send a message after #1, #2 are complete

I have the following code, the problem is I never see the log 'Add succes', does that mean either the remove or the add handler failed? if yes, how did I missing?

    let d = context.pipeline.removeHandler(name: "1").flatMap {
    context.pipeline.addHandler(
        NewHandler(), name: "1",
        position: .first
    )
    }

    d.whenSuccess {
    print("Add success")

context.channel.writeAndFlush(
self
.wrapInboundOut(NewMessage(
id: request.id + 1,
)),
promise: nil
)
}

I add print statement in 'whenFailure' . It said 'unremovableHandler'.

In NIO, by default, ChannelHandlers cannot be removed from the pipeline. This is because many handlers do not expect to be removed.

If this is a handler you wrote, add a conformance to RemovableChannelHandler.

Thanks for your help. I have changed my Handler to be RemovableChannelHandler. But I don't see my message getting sent.

My sequence is

  1. remove a handler in channel pipeline
  2. add a new handler in the same pipleline
  3. send a message after #1, #2 are complete
    So the remove handler works. But I am not sure if the add new handler succeed.
    So I try to check the return value of 'addHandler' , like this:

let d = context.pipeline.removeHandler(name: "1").flatMap {
let d2 = context.pipeline.addHandler(
NewHandler(), name: "1",
position: .first
)
}

but as soon as I add 'let d2 =' to get the return value of addHandler, I get compile error 'Generic parameter 'NewValue' could not be inferred'

Can you please tell me how to resolve?

Your original code looked like this:

let d = context.pipeline.removeHandler(name: "1").flatMap {
    context.pipeline.addHandler(
        NewHandler(), name: "1",
        position: .first
    )
}

d.whenSuccess {
    print("Add success")
    context.channel.writeAndFlush(
        self.wrapInboundOut(NewMessage(id: request.id + 1), promise: nil)
    )
}

Is this still your code? If it is, do you see Add success being printed?

Yes, I see 'Add success' get print. But I add another print statement after send, like this, that did not get print.

d.whenSuccess {
print("Add success")
context.channel.writeAndFlush(
self
.wrapInboundOut(NewMessage(
id: request.id + 1,
)),
promise: nil
)
print("Done send")
}

I have to reformat your text:

d.whenSuccess {
    print("Add success")
    context.channel.writeAndFlush(
        self.wrapInboundOut(NewMessage(id: request.id + 1,)),
        promise: nil
    )
    print("Done send")
}

Leaving aside the fact that I don't think the code can be an exact match for yours, as it cannot compile (there's an extra comma there), the only way to execute the first print and not the second print is if the program crashes. Nothing in the code you have written blocks, so if we see the first message we must either see a crash or the second message. Is your program crashing?

Let me explain what I am trying to accomplish.

My swift program can get and receives different Message objects

  • When gets ObjectA, it sends back ObjectB
  • When gets ObjectC, it sends back ObjectD

So i am following the example,

I add `Codec<ObjectA, ObjectB> as my handler, when it is time for my program to handle ObjectC, I remove the first handler , and then add a new handler Code<ObjectC, ObjectD>.

Is this the right approach?

That approach is entirely acceptable, sure.

From the doc, there is a method to ask the handler next in the pipeline to read:
fireChannelRead(

My question is why there is no corresponding fireChannelWrite to ask handler next in the pipeline to write?

There is: context.write. The “inbound” methods all begin with fire, the outbound methods do not.

Terms of Service

Privacy Policy

Cookie Policy