From 1aa5822556f5eff98cdb087420100c68fdb7fbb4 Mon Sep 17 00:00:00 2001 From: Ember Stevens Date: Wed, 7 Jun 2023 21:34:24 -0700 Subject: [PATCH 1/7] Updates daily flag count --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 33f60035..dffecaeb 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ ## LaunchDarkly overview -[LaunchDarkly](https://www.launchdarkly.com) is a feature management platform that serves over 100 billion feature flags daily to help teams build better software, faster. [Get started](https://docs.launchdarkly.com/home/getting-started) using LaunchDarkly today! +[LaunchDarkly](https://www.launchdarkly.com) is a feature management platform that serves trillions of feature flags daily to help teams build better software, faster. [Get started](https://docs.launchdarkly.com/home/getting-started) using LaunchDarkly today! [![Twitter Follow](https://img.shields.io/twitter/follow/launchdarkly.svg?style=social&label=Follow&maxAge=2592000)](https://twitter.com/intent/follow?screen_name=launchdarkly) @@ -18,7 +18,7 @@ Refer to the [SDK documentation](https://docs.launchdarkly.com/sdk/client-side/a ## Learn more -Check out our [documentation](https://docs.launchdarkly.com) for in-depth instructions on configuring and using LaunchDarkly. You can also head straight to the [complete reference guide for this SDK](https://docs.launchdarkly.com/sdk/client-side/android) or our [Javadocs](http://launchdarkly.github.io/android-client-sdk/). +Read our [documentation](https://docs.launchdarkly.com) for in-depth instructions on configuring and using LaunchDarkly. You can also head straight to the [complete reference guide for this SDK](https://docs.launchdarkly.com/sdk/client-side/android) or our [Javadocs](http://launchdarkly.github.io/android-client-sdk/). ## Testing From eb7d510969e131053931a9c8efd85e5f07ceed38 Mon Sep 17 00:00:00 2001 From: Ember Stevens Date: Wed, 7 Jun 2023 22:06:09 -0700 Subject: [PATCH 2/7] Removes check out --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index dffecaeb..affc2ff7 100644 --- a/README.md +++ b/README.md @@ -35,7 +35,7 @@ We encourage pull requests and other contributions from the community. Check out * Gradually roll out a feature to an increasing percentage of users, and track the effect that the feature has on key metrics (for instance, how likely is a user to complete a purchase if they have feature A versus feature B?). * Turn off a feature that you realize is causing performance problems in production, without needing to re-deploy, or even restart the application with a changed configuration file. * Grant access to certain features based on user attributes, like payment plan (eg: users on the ‘gold’ plan get access to more features than users in the ‘silver’ plan). Disable parts of your application to facilitate maintenance, without taking everything offline. -* LaunchDarkly provides feature flag SDKs for a wide variety of languages and technologies. Check out [our documentation](https://docs.launchdarkly.com/sdk) for a complete list. +* LaunchDarkly provides feature flag SDKs for a wide variety of languages and technologies. Read [our documentation](https://docs.launchdarkly.com/sdk) for a complete list. * Explore LaunchDarkly * [launchdarkly.com](https://www.launchdarkly.com/ "LaunchDarkly Main Website") for more information * [docs.launchdarkly.com](https://docs.launchdarkly.com/ "LaunchDarkly Documentation") for our documentation and SDK reference guides From af8502689651d610ba273991c95e3e2f029534af Mon Sep 17 00:00:00 2001 From: "ld-repository-standards[bot]" <113625520+ld-repository-standards[bot]@users.noreply.github.com> Date: Mon, 26 Jun 2023 22:46:52 +0000 Subject: [PATCH 3/7] Add file CODEOWNERS --- CODEOWNERS | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 CODEOWNERS diff --git a/CODEOWNERS b/CODEOWNERS new file mode 100644 index 00000000..7d0dac3c --- /dev/null +++ b/CODEOWNERS @@ -0,0 +1,2 @@ +# Repository Maintainers +* @launchdarkly/team-sdk From ede22d830899cf40b68c360a55af906ff0e3e4be Mon Sep 17 00:00:00 2001 From: Todd Anderson Date: Thu, 3 Aug 2023 10:40:42 -0500 Subject: [PATCH 4/7] Deprecating LDUser and related functionality. --- .../java/com/launchdarkly/sdk/android/LDClient.java | 10 ++++++++++ .../launchdarkly/sdk/android/LDClientInterface.java | 3 +++ 2 files changed, 13 insertions(+) diff --git a/launchdarkly-android-client-sdk/src/main/java/com/launchdarkly/sdk/android/LDClient.java b/launchdarkly-android-client-sdk/src/main/java/com/launchdarkly/sdk/android/LDClient.java index fceee94c..bc081500 100644 --- a/launchdarkly-android-client-sdk/src/main/java/com/launchdarkly/sdk/android/LDClient.java +++ b/launchdarkly-android-client-sdk/src/main/java/com/launchdarkly/sdk/android/LDClient.java @@ -200,7 +200,10 @@ public void onError(Throwable e) { * @return a {@link Future} which will complete once the client has been initialized * @see #init(Application, LDConfig, LDUser, int) * @see #init(Application, LDConfig, LDContext) + * + * @deprecated use {@link #init(Application, LDConfig, LDContext)} with {@link LDContext} */ + @Deprecated public static Future init(@NonNull Application application, @NonNull LDConfig config, @NonNull LDUser user) { @@ -257,7 +260,10 @@ public static LDClient init(Application application, LDConfig config, LDContext * @return the primary LDClient instance * @see #init(Application, LDConfig, LDUser) * @see #init(Application, LDConfig, LDContext, int) + * + * @deprecated use {@link #init(Application, LDConfig, LDContext, int)} with {@link LDContext} */ + @Deprecated public static LDClient init(Application application, LDConfig config, LDUser user, int startWaitSeconds) { return init(application, config, LDContext.fromUser(user), startWaitSeconds); } @@ -396,6 +402,10 @@ public Future identify(LDContext context) { return identifyInstances(contextDecorator.decorateContext(context, getSharedLogger())); } + /** + * @deprecated use {@link #identify(LDContext)} with {@link LDContext} + */ + @Deprecated @Override public Future identify(LDUser user) { return identify(LDContext.fromUser(user)); diff --git a/launchdarkly-android-client-sdk/src/main/java/com/launchdarkly/sdk/android/LDClientInterface.java b/launchdarkly-android-client-sdk/src/main/java/com/launchdarkly/sdk/android/LDClientInterface.java index 7f9be138..d8fe7a2e 100644 --- a/launchdarkly-android-client-sdk/src/main/java/com/launchdarkly/sdk/android/LDClientInterface.java +++ b/launchdarkly-android-client-sdk/src/main/java/com/launchdarkly/sdk/android/LDClientInterface.java @@ -146,7 +146,10 @@ public interface LDClientInterface extends Closeable { * @return a Future whose success indicates the flag values for the new evaluation context have * been stored locally and are ready for use * @see #identify(LDContext) + * + * @deprecated use {@link #identify(LDContext)} with {@link LDContext} */ + @Deprecated Future identify(LDUser user); /** From e9378f68e2519f80bae958ffaf3cff500bdd3560 Mon Sep 17 00:00:00 2001 From: Todd Anderson Date: Thu, 3 Aug 2023 11:58:00 -0500 Subject: [PATCH 5/7] Updating java-sdk-common to use version with LDUser deprecation --- launchdarkly-android-client-sdk/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/launchdarkly-android-client-sdk/build.gradle b/launchdarkly-android-client-sdk/build.gradle index bf565e1d..62401158 100644 --- a/launchdarkly-android-client-sdk/build.gradle +++ b/launchdarkly-android-client-sdk/build.gradle @@ -64,7 +64,7 @@ ext.versions = [ "jacksonCore": "2.10.5", "jacksonDatabind": "2.10.5.1", "junit": "4.13", - "launchdarklyJavaSdkCommon": "2.0.1", + "launchdarklyJavaSdkCommon": "2.1.0", "launchdarklyJavaSdkInternal": "1.0.0", "launchdarklyLogging": "1.1.1", "okhttp": "4.9.2", From 260f2ffbcda0dfa560e6e2f3e21eade9f8d87395 Mon Sep 17 00:00:00 2001 From: Todd Anderson <127344469+tanderson-ld@users.noreply.github.com> Date: Tue, 27 Feb 2024 17:03:18 -0600 Subject: [PATCH 6/7] =?UTF-8?q?fix:=20eliminates=20executor=20in=20StreamD?= =?UTF-8?q?ataSource=20that=20was=20not=20cleaned=20up=20=E2=80=A6=20(#313?= =?UTF-8?q?)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Backporintg to 4.x Same as https://github.com/launchdarkly/android-client-sdk-private/pull/312 --- .../sdk/android/LDClientTest.java | 3 +- .../sdk/android/BackgroundThreadExecutor.java | 52 ------------------- .../sdk/android/StreamingDataSource.java | 17 ++++-- 3 files changed, 14 insertions(+), 58 deletions(-) delete mode 100644 launchdarkly-android-client-sdk/src/main/java/com/launchdarkly/sdk/android/BackgroundThreadExecutor.java diff --git a/launchdarkly-android-client-sdk/src/androidTest/java/com/launchdarkly/sdk/android/LDClientTest.java b/launchdarkly-android-client-sdk/src/androidTest/java/com/launchdarkly/sdk/android/LDClientTest.java index 38c57510..59272e12 100644 --- a/launchdarkly-android-client-sdk/src/androidTest/java/com/launchdarkly/sdk/android/LDClientTest.java +++ b/launchdarkly-android-client-sdk/src/androidTest/java/com/launchdarkly/sdk/android/LDClientTest.java @@ -16,6 +16,7 @@ import java.io.IOException; import java.util.concurrent.ExecutionException; +import java.util.concurrent.Executors; import java.util.concurrent.Future; import static org.junit.Assert.assertEquals; @@ -153,7 +154,7 @@ public void testDoubleClose() throws IOException { @Test public void testInitBackgroundThread() throws Exception { - Future backgroundComplete = new BackgroundThreadExecutor().newFixedThreadPool(1).submit(() -> { + Future backgroundComplete = Executors.newSingleThreadExecutor().submit(() -> { try { try (LDClient ldClient = LDClient.init(application, makeOfflineConfig(), ldUser).get()) { assertTrue(ldClient.isInitialized()); diff --git a/launchdarkly-android-client-sdk/src/main/java/com/launchdarkly/sdk/android/BackgroundThreadExecutor.java b/launchdarkly-android-client-sdk/src/main/java/com/launchdarkly/sdk/android/BackgroundThreadExecutor.java deleted file mode 100644 index a05230a5..00000000 --- a/launchdarkly-android-client-sdk/src/main/java/com/launchdarkly/sdk/android/BackgroundThreadExecutor.java +++ /dev/null @@ -1,52 +0,0 @@ -package com.launchdarkly.sdk.android; - -import android.os.Process; - -import androidx.annotation.NonNull; - -import java.util.concurrent.ExecutorService; -import java.util.concurrent.LinkedBlockingQueue; -import java.util.concurrent.ThreadFactory; -import java.util.concurrent.ThreadPoolExecutor; -import java.util.concurrent.TimeUnit; - -/** - * Executes all threads with priority android.os.Process.THREAD_PRIORITY_BACKGROUND. - */ -class BackgroundThreadExecutor { - - private final ThreadFactory threadFactory; - - BackgroundThreadExecutor() { - this.threadFactory = new PriorityThreadFactory(Process.THREAD_PRIORITY_BACKGROUND); - } - - @SuppressWarnings("SameParameterValue") - ExecutorService newFixedThreadPool(int nThreads) { - return new ThreadPoolExecutor(nThreads, nThreads, 0L, TimeUnit.MILLISECONDS, - new LinkedBlockingQueue(), threadFactory); - } - - private static class PriorityThreadFactory implements ThreadFactory { - - private final int threadPriority; - - PriorityThreadFactory(int threadPriority) { - this.threadPriority = threadPriority; - } - - @Override - public Thread newThread(@NonNull final Runnable runnable) { - return new Thread(() -> { - try { - Process.setThreadPriority(threadPriority); - } catch (Throwable ignored) { - // ignore - } - runnable.run(); - }); - } - - } - -} diff --git a/launchdarkly-android-client-sdk/src/main/java/com/launchdarkly/sdk/android/StreamingDataSource.java b/launchdarkly-android-client-sdk/src/main/java/com/launchdarkly/sdk/android/StreamingDataSource.java index 96b7dcf2..a429e8df 100644 --- a/launchdarkly-android-client-sdk/src/main/java/com/launchdarkly/sdk/android/StreamingDataSource.java +++ b/launchdarkly-android-client-sdk/src/main/java/com/launchdarkly/sdk/android/StreamingDataSource.java @@ -22,7 +22,6 @@ import com.launchdarkly.sdk.json.SerializationException; import java.net.URI; -import java.util.concurrent.ExecutorService; import java.util.concurrent.TimeUnit; import okhttp3.OkHttpClient; @@ -63,7 +62,6 @@ final class StreamingDataSource implements DataSource { private final boolean streamEvenInBackground; private volatile boolean running = false; private boolean connection401Error = false; - private final ExecutorService executor; private final DiagnosticStore diagnosticStore; private long eventSourceStarted; private final LDLogger logger; @@ -87,7 +85,6 @@ final class StreamingDataSource implements DataSource { this.streamEvenInBackground = streamEvenInBackground; this.diagnosticStore = ClientContextImpl.get(clientContext).getDiagnosticStore(); this.logger = clientContext.getBaseLogger(); - executor = new BackgroundThreadExecutor().newFixedThreadPool(2); } public void start(@NonNull Callback resultCallback) { @@ -241,12 +238,22 @@ public void stop(final @NonNull Callback onCompleteListener) { logger.debug("Stopping."); // We do this in a separate thread because closing the stream involves a network // operation and we don't want to do a network operation on the main thread. - executor.execute(() -> { + // This code originally created a one-shot thread for shutting down the event source, but at some point + // an Executor was introduced. A thread leak bug was introduced with that Executor because the Executor + // was not cleaned up. The thread leak bug was brought to our attention in + // https://github.com/launchdarkly/android-client-sdk/issues/234 . Over time, the code evolved to no longer + // need the Executor to be long lived. Reverting to the one-shot thread approach is sufficient to address + // the bug. A more appropriate fix would be to refactor/unify the various task executors in the code base + // and pass one of those executors in to be used for this purpose. That refactoring is not without risk and + // will be reserved for a future major version. + new Thread(() -> { + // Moves the current Thread into the background. + android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_BACKGROUND); stopSync(); if (onCompleteListener != null) { onCompleteListener.onSuccess(null); } - }); + }).start(); } @Override From c5c7947f737bb9d40ae4e3a8099bf6f2d235ba56 Mon Sep 17 00:00:00 2001 From: Todd Anderson <127344469+tanderson-ld@users.noreply.github.com> Date: Thu, 29 Feb 2024 11:35:10 -0600 Subject: [PATCH 7/7] chore: adding 4.x as releasable branch --- .ldrelease/config.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.ldrelease/config.yml b/.ldrelease/config.yml index 3357c5c8..8c47abb1 100644 --- a/.ldrelease/config.yml +++ b/.ldrelease/config.yml @@ -18,6 +18,7 @@ jobs: branches: - name: main + - name: 4.x - name: 3.x documentation: