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

Event tracking in a multiprocess app #428

Closed
mhelder opened this issue Mar 9, 2020 · 6 comments
Closed

Event tracking in a multiprocess app #428

mhelder opened this issue Mar 9, 2020 · 6 comments

Comments

@mhelder
Copy link

mhelder commented Mar 9, 2020

I'm working on integrating the Adjust SDK in a multiprocess app. It's basically a radio app that runs a service in a separate (private) process. Somewhat like this:

<service
    android:name="com.example.RadioService"
    android:foregroundServiceType="mediaPlayback"
    android:process=":radio"
    android:stopWithTask="true">
    <intent-filter>
        <action android:name="android.media.browse.MediaBrowserService" />
    </intent-filter>
</service>

Throughout the app, several events are being triggered. These all show up fine when I run the network traffic through a proxy. However, the same cannot be said for events triggered from the RadioService. To me it looks like events from the app's 'main' process work fine, but not the radio process.

I haven't really done a deep-dive yet, but did track the call stack down to ActivityHandler.trackEventI. I also checked that this method doesn't return on any of the initial if statements, but that's as far as I've looked for now.

Before I go any further, I was wondering if there are any known limitations around using the Adjust SDK in a multiprocess app? I couldn't find anything in the docs related to this. Apologies if I overlooked any other sources of information.

@uerceg
Copy link
Contributor

uerceg commented Mar 9, 2020

Hi @mhelder

And thanks for detailed explanation. Yes, this is limitation. Different processes in Android app are getting their own instance of Dalvik VM causing memory space between them not to be shared. Our SDK, once initialised, exists as singleton instance, but within memory space of the process you actually initialised it in. Which means that if you did Adjust.onCreate/Adjust.onResume sequence to initialise and start SDK in one process and are trying just to perform Adjust.trackEvent in another process, it just won't work since SDK instance isn't initialised and started in process where you're trying to perform event tracking.

In case you have some inter process communication inside of your app up and running, my advice would be to ping your process in which SDK has been initialised and started from these other processes and from there perform any action on Adjust SDK you need.

In case you have any further questions, feel free to ping.

Cheers

@mhelder
Copy link
Author

mhelder commented Mar 10, 2020

Hi @uerceg,

Thanks for the prompt reply!

Our SDK, once initialised, exists as singleton instance, but within memory space of the process you actually initialised it in. (...) it just won't work since SDK instance isn't initialised and started in process where you're trying to perform event tracking.

Well, that's the thing: the SDK is initialised in both processes. As a result, at runtime each process will have its own singleton instance. As I mentioned before, I did already confirm that ActivityHandler.trackEventI is invoked and that it doesn't return from any of the initial if statements.

Anyways, I decided to dig a little deeper and noticed this at the bottom of trackEventI:

// if it is in the background and it can send, start the background timer
if (adjustConfig.sendInBackground && internalState.isInBackground()) {
    startBackgroundTimerI();
}
writeActivityStateI();

This made me realise that the process running the RadioService will always be considered to be in the background, because it has no UI (well, except for a notification) and no activities that will ever be resumed (so no calls to Adjust.onResume()). Enabling background tracking (per documentation) for the :radio process only, resulted in events from the service to also immediately be tracked.

Upon further investigation, even without background tracking enabled, it looks like events are still persisted to disk (into a file called AdjustIoPackageQueue). It also seems like these events aren't picked up and sent until next app start (triggered from sendFirstPackage()) - if you're lucky...

... because there are now two instances of the SDK reading and writing to the same files. As far as I could tell, there is no form of locking in place to deal with this, meaning the r/w's from the two instances will interfere with each other. So events/stats will be lost along the way and files may end up getting corrupted and flushed altogether.

Long story short, I'll probably go for an IPC solution for now so that the Adjust SDK is only initialised in the app's 'main' process and all event tracking is happening in one place (& process of course).

Thanks for the help 👍

@uerceg
Copy link
Contributor

uerceg commented Mar 10, 2020

@mhelder Ah, okay, now I see the setup. So you do have it instantiated in both processes. Let us double check this and will reply to you once we run the tests in setup you're having.

@rajib-coder
Copy link

Multi process this device app

@rajib-coder
Copy link

[http//www.uber navigation.com](uber

@uerceg
Copy link
Contributor

uerceg commented Dec 14, 2023

I just wanted to follow up on this one to conclude that for the time being, this setup is something which SDK v4 is not really capable to gracefully handle. In our upcoming SDK v5 release in 2024, we tried to address the issue with multiple instances and as of that version on, one will be able to have multiple SDK instances running in parallel (in same or different process(es), doesn't matter) which will be able to write to their own storage space. I think that multi-process apps still remain a bit of a challenge in some cases and we'll try to see if we can make v5 handle those scenarios in a more convenient ways. Thank you one more time for all the research / comments / advices. We'll keep the reference to this ticket in our v5 backlog and keep you posted on any progress about this topic.

In the meantime, I'm gonna close this ticket, but feel free to comment / ping in here if you have any further questions.

Cheers

@uerceg uerceg closed this as completed Dec 14, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants