influxdata / influxdb-client-swift

InfluxDB (v2+) Client Library for Swift
https://influxdata.github.io/influxdb-client-swift/
MIT License
27 stars 8 forks source link

async/await update to Swift API #54

Closed sillygoose closed 2 years ago

sillygoose commented 2 years ago

Proposal: Title says it all.

Current behavior: I have been using a semaphore to wait for the query results to be returned but this gets a warning in Swift 5.7 and will be an error in Swift 6:

    func getChargeList(from: Int, until: Int) async -> [Charge] {
        let flux =  """
                    from(bucket: "\(self.bucket)")
                        ...
                    """
        let queryTask = Task { () -> [Charge] in
            let s = DispatchSemaphore(value: 0)
            var chargeSessions: [Charge] = []
            self.client.queryAPI.query(query: flux) { response, error in
                if let error = error {
                    print("getChargeList error: \(error)")
                }
                if let response = response {
                    do {
                        ...
                }
                s.signal()
            }
            s.wait()
            return chargeSessions
        }
        return await queryTask.value
    }

As of Swift 5.7 I get a warning

Instance method 'wait' is unavailable from asynchronous contexts; Await a Task handle instead; this is an error in Swift 6

Desired behavior: response, error = await self.client.queryAPI.query(query: flux) seems to be one possibility. Still the same amount of working picking the fields out the response.

Alternatives considered: I haven't found a solution yet but I admit to being an amateur Swift/InfluxDB user.

Use case: I guess async/await is the future of Swift asynchronous programming and lets the code be read linearly.

bednar commented 2 years ago

Hi @sillygoose,

thanks for using our client.

The client already supports async/await so you are able to use:

func getChargeList(from: Int, until: Int) async -> [Charge] {
        let flux =  """
                    from(bucket: "\(self.bucket)")
                        ...
                    """

        var chargeSessions: [Charge] = []
        let records = try await self.client.queryAPI.query(query: flux) 
        records.forEach { chargeSessions.append(make_charge_from_record($0))}
        return chargeSessions
    }

For more info see following example: https://github.com/influxdata/influxdb-client-swift/blob/2d4ce6eb0bb66a20e53501171891470ae20ffa09/Examples/AsyncAwait/Sources/AsyncAwait/AsyncAwait.swift#L53

Regards

sillygoose commented 2 years ago

My bad, didn't see any mention in the repo README file and did not think to look at examples.

Ported my old style code and I can confirm that it worked very well in async/awaitl. Thanks for the hard work on a great library!