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

[pigeon] Adds support of TaskQueue for Swift #8501

Open
wants to merge 8 commits into
base: main
Choose a base branch
from

Conversation

feduke-nukem
Copy link

  • Adds support of TaskQueue for Swift
  • Adds related generator tests for Objective-c, Kotlin, Swift and Java

closes 111512

Pre-launch Checklist

  • I read the [Contributor Guide] and followed the process outlined there for submitting PRs.
  • I read the [Tree Hygiene] page, which explains my responsibilities.
  • I read and followed the [relevant style guides] and ran the auto-formatter. (Unlike the flutter/flutter repo, the flutter/packages repo does use dart format.)
  • I signed the [CLA].
  • The title of the PR starts with the name of the package surrounded by square brackets, e.g. [shared_preferences]
  • I [linked to at least one issue that this PR fixes] in the description above.
  • I updated pubspec.yaml with an appropriate new version according to the [pub versioning philosophy], or this PR is [exempt from version changes].
  • I updated CHANGELOG.md to add a description of the change, [following repository CHANGELOG style], or this PR is [exempt from CHANGELOG changes].
  • I updated/added relevant documentation (doc comments with ///).
  • I added new tests to check the change I am making, or this PR is [test-exempt].
  • All existing and new tests are passing.

@@ -851,6 +854,7 @@ if (wrapped == nil) {
}) {
return 'try instanceManager.removeAllObjects()';
},
taskQueueType: TaskQueueType.serial,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is serial task queue the only supported type? do we support concurrent queue?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

image

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do we support concurrent queue?

We have never had a use case in our own plugins for concurrent queues, AFAIK nobody else has ever requested it, and I would not expect concurrent task queues to be a common use case in platform channels, so currently we have had no reason to implement it.

indent.writeln(
'let $varChannelName = FlutterBasicMessageChannel(name: "$channelName", binaryMessenger: binaryMessenger, codec: codec)');
String? taskQueue;
if (taskQueueType != TaskQueueType.serial) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

im confused here - does TaskQueueType.serial mean it's not background queue? If it means it's a main queue, maybe we should rename to serialMainQueue instead.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Doc states:

  /// Handlers are invoked serially on the default thread. This is the value if
  /// unspecified.

Copy link
Contributor

@stuartmorgan stuartmorgan Jan 24, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

im confused here - does TaskQueueType.serial mean it's not background queue?

No, it means that all calls on that API object using the serial task queue will be executed in order, each one completing before the next starts.

As compared with, e.g., a default NSOperationQueue, which will dispatch jobs into a thread pool, and might run everything in parallel on N different threads.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Handlers are invoked serially on the default thread.

Is the "default thread" referring to main thread?

Copy link
Contributor

@stuartmorgan stuartmorgan Jan 24, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, it's an arbitrary background thread. That's why the API called by the generated code is makeBackgroundTaskQueue.

Calling things serially on the main thread is what platform channels do by default, and what they always did before the creation of the task queue API. The whole point of adding task queues to the channel APIs in the engine was to move them off of the main thread.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please forgive my numerous questions, I think I may be missing something.

What you just described sounds very like the .serialBackgroundThread case, rather than the .serial case. Also, the code here is:

if NOT serial { // the only other case is serialBackgroundThread
  use makeBackgroundTaskQueue API
}

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What you just described sounds very like the .serialBackgroundThread case, rather than the .serial case.

Sorry, I forgot that Pigeon for some reason has a task queue enum value that actually means "don't use task queues". I have no idea why it was written that way; it's incredibly confusing.

So yes, it's the main thread and everything I said was wrong.

maybe we should rename to serialMainQueue instead

We should probably just remove it, or if we keep it call it the even simpler none, but either way that's out of scope here.

let result = try api.echoAllTypesTaskQueueBackground(everythingArg)
reply(wrapResult(result))
} catch {
reply(wrapError(error))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IIUC reply should still be called on main thread.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it be sufficient to add?

DispatchQueue.main.async {
  reply(wrapResult(result))
}

like it is mentioned in docs

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

However, I wonder why it was not done for others generators in the past.

Outputs for methods marked with TaskQueue:

Objective-c:
image

Java:
image

Kotlin:
image

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IIUC reply should still be called on main thread.

Please see the second bullet point here.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IIUC reply should still be called on main thread.

Please see the second bullet point here.

Sorry i misread your message.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looking at it again, I must have misunderstood the 3rd bullet point as the reply call. Sorry for the confusion.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I must have misunderstood the 3rd bullet point as the reply call

Does it have any implications for the discussion in this PR?

Apologies if I’m missing something.

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

Successfully merging this pull request may close these issues.

[pigeon] Support TaskQueue when using Swift
3 participants