-
Notifications
You must be signed in to change notification settings - Fork 21
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
feat: Server Side Swift #42
Conversation
Hi @richardpiazza , Thank you for supporting Amplitude!! As we are not familiar with server-side Swift and don't have the Linux machine at the hand, some questions regarding this PR:
Thanks! |
Happy to help out...
|
Thank you for adding this and your detailed explanation! I will clone the fork and try the example in my local. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The change looks good overall to me, thanks for the contribution! Some comments:
- I tried to run the server locally in XCode (macOS), however, there seems a issue with the Timer (flush is triggered automatically). I am not sure whether it is OS issue or my local setup issue. Will check with my fellow to diagnose it.
- For the server-side usage, I don't think we need session events. @yuhao900914 , I know we have the config
trackingSessionEvents
, do you have any suggestion here?
Tested with @yuhao900914 , the Timer doesn't work in her local either. To elaborate it a little bit:
@richardpiazza let us know if you have any clue on this, thanks! |
I think I traced why the events wouldn't have been sending... It boils down to if !(self.amplitude?._inForeground ?? false) {
// This just gets called repeatedly.
sessionEvents = self.amplitude?.startOrContinueSession(timestamp: eventTimeStamp)
} else {
_ = self.amplitude?.refreshSessionTime(timestamp: eventTimeStamp)
} On iOS and macOS there are plugins that track the lifecycle and indicate when the app is in the foreground. When running server-side, an application would always be considered foreground. To work around this, I created a Might need to look at that logic or expose the ability to manually start a session ( |
Sorry, I think events-not-sending-issue is for all events, not just for the session events. More details:
I just pull the latest code with the plugin, think the Timer is still not working in my local. The Swift web server is running in the terminal, but there is no events sent out (once the total unsent events count reaches 30, it will trigger the flush too). Curious does the similar issue happen in your development environment? Thank you! |
I dug further into the Task {
repeat {
try? await Task.sleep(nanoseconds: UInt64(interval) * 1_000_000_000)
fire()
} while (repeating)
// If the timer doesn't repeat, mark as 'suspended' after firing.
suspend()
} When suspended, the task is canceled and nullified. On resume, the task is recreated and runs once/repeatedly depending on the timers parameters. I tested this on iOS, macOS, and Linux and seems to work across all platforms (plus it's using a swift language feature!) Also, I reverted the addition of the |
Thank you @richardpiazza! Seems github is having issue right now, the actions cannot be executed. I will give it a try later to see. |
@richardpiazza , sorry for the delay, and thank you for looking into the solution! I tried the new code locally, and I think the Timer is still not working for me, it doesn't automatically flush event. I ran the server in my Xcode (Version 14.2 (14C18)). Steps to reproduce:
Result:
Would you mind sharing your configuration or steps to run the server-side app with events sent successfully? Thanks! |
@liuyang1520 Oh wow, entirely a screwup on my part. I only was confirming that the I have finally identified exactly why the The most direct fix would be to use a One other direction I explored was do pick a queue based on the environment, but I couldn't find a direct way of detecting in the execution was as part of a 'normal' application or a server. static var queue: DispatchQueue {
#if os(Linux)
return .global()
#elseif os(macOS)
// running in application window or executable/server?
return ?
#else
return .main
#endif
} I'd be happy to continue exploring other options as well. |
@richardpiazza good job on finding the root cause for the timer! I pulled the code and run the server example, it does fire the events periodically, I think the cause is identified here. Agree with you that it might cause unexpected issues when modifying the queue to
Let me know your thoughts on this or any new option you found. Thanks! |
@liuyang1520 Sorry about the delay in getting back to you. It's been a busy week. Were you and your team able to have any discussions on the topics raised? I'll give a little feedback below, but I'll yield to the teams direction for the project.
I think one way to work around needing to specify the The runtime switch seems like a good stepping stone, but should ultimately be considered temporary. |
Hey there richardpiazza, I see that you have made some updates to the Amplitude library to support server-side Swift on Linux. That's great news, as it expands the reach of the library and makes it even more versatile. |
Hello. Just wondering if there has been any further internal discussion on this PR? |
1c5e50a
to
4cbfeb2
Compare
Summary
This PR adds support for server-side-swift, specifically on Linux.
Although the repository specially called out Apple platforms (This is Amplitude's latest version of the iOS SDK, covering iOS/tvOS/macOS/watchOS.), Swift as a language is growing beyond those specific usages. With a few modifications, this library can be adapted to run on other Swift native environments.
OSLog
by checking for the ability to importos.log
FoundationNetworking
which has the class definition for networking-related types.LinuxVendorSystem
which uses theProcessInfo
to determine some OS specifics.XCTUnwrap
allowed for removing of the forced unwrap optionals.Checklist