0

I just started with SwiftNIO and I used this code for the first try:

let group = MultiThreadedEventLoopGroup(numberOfThreads: 1)
let bootstrap = ClientBootstrap(group: group)
    // Enable SO_REUSEADDR.
    .channelOption(ChannelOptions.socket(SocketOptionLevel(SOL_SOCKET), SO_REUSEADDR), value: 1)
defer {
    try? group.syncShutdownGracefully()
}

do {
    let channel = try bootstrap.connect(host: "127.0.0.1", port: 1234).wait()
    try channel.closeFuture.wait()
} catch let error {
    print(error)
}

It works and I get printed an error, because my server is not running.

But if I bring that code to a class, nothing happens:

class Client {

    let bootstrap: ClientBootstrap

    init() {
        let group = MultiThreadedEventLoopGroup(numberOfThreads: 1)
        self.bootstrap = ClientBootstrap(group: group)
            // Enable SO_REUSEADDR.
            .channelOption(ChannelOptions.socket(SocketOptionLevel(SOL_SOCKET), SO_REUSEADDR), value: 1)
        defer {
            try? group.syncShutdownGracefully()
        }
    }

    func connect(host: String, port: Int) throws {
        let channel = try self.bootstrap.connect(host: host, port: port).wait()
        try channel.closeFuture.wait()
    }
}

let client = Client()
do {
    try client.connect(host: "127.0.0.1", port: 1234)
} catch let error {
    print(error)
}

What am I doing wrong?

Lupurus
  • 3,618
  • 2
  • 29
  • 59

1 Answers1

0

In what context is the original code running? It's unusual to see a defer in an init method, particularly right at the end - it will be executed as soon as init is finished, whereas the defer in your original code will be executed after the do / catch block is performed.

You probably want the shutdown code to be in the deinit method of your Client class.

jrturton
  • 118,105
  • 32
  • 252
  • 268
  • Just found it out by myself. Sorry for that stupid question, your totally right! – Lupurus Oct 03 '19 at 10:25
  • 2
    I would highly recommend not using `deinit` to shut down the MultiThreadedEventLoop group. This might lead to deadlocks or crashes if the deinit is run from the EventLoop that you're trying to shut down (and you cannot control the thread deinit is run from). Usually, one process should have one EventLoopGroup. I would suggest passing the EventLoopGroup into the init instead of creating it there. main.swift is a great place to create the EventLoopGroup. – Johannes Weiss Oct 03 '19 at 11:23
  • @JohannesWeiss I'm sure you're right :) . I know nothing about SwiftNIO, I was just commenting on the code in the question. Thankyou for the clarification – jrturton Oct 03 '19 at 13:14