Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to run sync operations then concurrent operations in a queue? #14

Closed
Kalzem opened this issue Jan 23, 2019 · 7 comments
Closed

How to run sync operations then concurrent operations in a queue? #14

Kalzem opened this issue Jan 23, 2019 · 7 comments

Comments

@Kalzem
Copy link

Kalzem commented Jan 23, 2019

I have to run task A, B, C and D.
Task B needs A.
Tasks C and D need B.

I would like to run a queue in this order

  1. Task A
  2. Task B (needs A)
  3. Task C and D in parallel (both need B)

What would be the easiest way to achieve it with Queuer?

@FabrizioBrancati
Copy link
Owner

FabrizioBrancati commented Jan 23, 2019

You can do it like that:

let queue = Queuer(name: "MyCustomQueue")

let concurrentOperationA = ConcurrentOperation { _ in
    /// Your task here
}
let concurrentOperationB = ConcurrentOperation { _ in
    /// Your task here
}
let concurrentOperationC = ConcurrentOperation { _ in
    /// Your task here
}
let concurrentOperationD = ConcurrentOperation { _ in
    /// Your task here
}

queue.addChainedOperations([concurrentOperationA, concurrentOperationB]) {
    /// Your completion task here
}
queue.addChainedOperations([concurrentOperationB, concurrentOperationC]) {
    /// Your completion task here
}
queue.addChainedOperations([concurrentOperationB, concurrentOperationD]) {
    /// Your completion task here
}

/// Add this if you want to have a queue completion handler
queue.addCompletionHandler {
    /// Your completion task here
}

Let me know if this works for you 😄

@Kalzem
Copy link
Author

Kalzem commented Jan 24, 2019

I tried it and it's not exactly what I am looking for because doing so, operation B is triggered 3 times.

So I dug a bit and I came up with the perfect solution for my case:

class GroupOperation: ConcurrentOperation {
    let queue = OperationQueue()
    var operations: [ConcurrentOperation] = []
    
    override func execute() {
        self.queue.addOperations(self.operations, waitUntilFinished: true)
        self.finish(success: success)
    }
}

Then I call

let groupWithCAndD = GroupOperation()
groupWithCAndD.operations([operationC, operationD])
queue.addChainedOperations([
    operationA,
    operationB,
    groupWithCAndD
])

And voilà !

Maybe it can be interesting to add a class GroupOperation in Queuer? And also make the API of queue.addChainedOperations more flexible, for example it can allow an "infinite" number of array of array of operations like this:

addChainesOperations([ opA, opB, [opC, [opD, opE]]])

@Kalzem
Copy link
Author

Kalzem commented Jan 24, 2019

Obviously this solution doesn't fit Queuer perfectly as there is no handling of retry etc, but maybe @FabrizioBrancati you can improve the lib with such feature? I would gladly help if I can.

@FabrizioBrancati
Copy link
Owner

I would really like to improve the addChainedOperations(_:) API!
Your idea sounds great, we need to understand how to achieve that.

Currently, the B task is executed 3 times, because of this line...

Maybe a solution can be to add an addChainedOperations(_:) to ConcurrentOperation class without that line.

I will be very happy to see a PR about that! Please don't hesitate on doing it!

@FabrizioBrancati
Copy link
Owner

Have you already started working on that? 😄

@Kalzem
Copy link
Author

Kalzem commented Feb 4, 2019

I will give it a try this week! :)

@FabrizioBrancati
Copy link
Owner

I'm closing this issue, because this PR has been merged and is now available on the develop branch 🎉

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants