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

wrap launch darkly in CLI to avoid bringing in new deps #12801

Merged
merged 31 commits into from
Apr 22, 2022

Conversation

mjkkirschner
Copy link
Member

@mjkkirschner mjkkirschner commented Apr 14, 2022

Purpose

Updated 4/18 to short lived CLI process.

An alternative to:
#12790

in this PR instead of pulling LD sdk and its dependencies into the same process as Dynamo/Host - it's wrapped in a CLI following a very similar pattern to the markdown2html conversion tool.

How it works:

  • currently, the CLI tool is started at dynamo startup, initializes a connection with LD, asks LD for all the current user's known flags and their values, and will immediately send back a json object containing that data.
launch darkly initalized
2022-04-19 18:50:24Z : LD startup time: 897 
2022-04-19 18:50:26Z : <<<<<InitDone>>>>>
2022-04-19 18:50:27Z : feature flag exe starting
2022-04-19 18:50:30Z : <<<<<Sod>>>>>
2022-04-19 18:50:32Z : {"EasterEggIcon1":true,"EasterEggMessage1":"Hello fellow dynamo developers, have a great day."}
2022-04-19 18:50:34Z : <<<<<Eod>>>>>

I've added the start of data messages so I can safely log other information.

The process then shuts down.

If somehow Dynamo shuts down during the brief window where the flags were being retrieved, the CLI will also shut down if the host process is no longer running. It checks this every 10 seconds.

The CLI tool/wrapper are started on another thread using Task.Run to avoid blocking the startup of DynamoModel/DynamoView - this makes synchronizing when to check flags a bit complicated, so I've added an event that can be subscribed to - still, it's not foolproof as the event may have fired before you have a chance to subscribe to it, in this case the checkFlag API can be queried directly.

If we encounter a case in the future where we absolutely must control DynamoModel/DynamoView constructors via feature flags, then we can just remove the Task.Run and wait for the flags to be retrieved synchronously, and get rid of the event.

Screen Shot 2022-04-20 at 4 05 02 PM

issues/TODO:

  • The LaunchDarklyClient.Sdk refuses to run when its been merged with ILMerge - I have not tried merging only some of the deps- but it happily works if all the deps are in a separate DynamoFeatureFlags folder.
  • Tests
  • Test manually in Revit to make sure no issues with Task.Run/sync context.
  • std.error is redirected and read async to avoid the buffer filling up in a long running process.

Declarations

Check these if you believe they are true

  • The codebase is in a better state after this PR
  • Is documented according to the standards
  • The level of testing this PR includes is appropriate
  • User facing strings, if any, are extracted into *.resx files
  • All tests pass using the self-service CI.
  • Snapshot of UI changes, if any.
  • Changes to the API follow Semantic Versioning and are documented in the API Changes document.
  • This PR modifies some build requirements and the readme is updated

Release Notes

Add FeatureFlagsManager internal component for querying live feature flags.

Reviewers

(FILL ME IN) Reviewer 1 (If possible, assign the Reviewer for the PR)

(FILL ME IN, optional) Any additional notes to reviewers or testers.

FYIs

(FILL ME IN, Optional) Names of anyone else you wish to be notified of

instantiate feature flags manager in core
test message box in view
add feature flags man project with config file
update compiler unsafe to v 5
wrap startup in try catch
unsub logger handler
add prod key
use shared key
add try catch and logging around LD api methods
move under tools dir
refactor out small base class
@pinzart90
Copy link
Contributor

pinzart90 commented Apr 14, 2022

Maybe we can have a self destruct functionality inside the launchDarkly process. In case it becomes a zombie..
It could periodically check for the existence of the parent process (the dynamo process). If the dynamo process is not alive anymore...then self destruct.
We can pass the dynamo process id or name when the LD process is created...

@mjkkirschner
Copy link
Member Author

Maybe we can have a self destruct functionality inside the launchDarkly process. In case it becomes a zombie..
It could periodically check for the existence of the parent process (the dynamo process). If the dynamo process is not alive anymore...then self destruct.
We can pass the dynamo process id or name when the LD process is created...

good idea!

I'm looking at the build failure. It's not obvious to me which path doesn't exist.

@pinzart90
Copy link
Contributor

Regarding deadlocks or lack of timeouts...
One other option (not saying it is better/faster) would be to make the separate process an http server

@sm6srw
Copy link
Contributor

sm6srw commented Apr 14, 2022

Is there any fundamental difference in this implementation compared to the markdown tool? I kind of remember that I had very few issues with zombies in the end with the markdown tool. One thing that could cause this is if the process creates threads that is not properly destroyed. Maybe something that happens in the LD SDK?

@mjkkirschner mjkkirschner marked this pull request as draft April 15, 2022 16:48
@mjkkirschner
Copy link
Member Author

moved to draft while I try to reproduce the test hang locally.

@mjkkirschner mjkkirschner marked this pull request as ready for review April 16, 2022 19:52
@mjkkirschner
Copy link
Member Author

this is no longer timing out the build machines - but there is a single failure, looking at it.

@mjkkirschner mjkkirschner changed the title WIP experiment to wrap launch darkly in CLI to avoid bringing in new deps WIP wrap launch darkly in CLI to avoid bringing in new deps Apr 19, 2022

//run process startup/reading on another thread so we don't block dynamo startup.
//if we end up needing to control aspects of dynamo model or view startup that we can't make
//event based/async then just run this on main thread - ie get rid of the Task.Run()
Copy link
Contributor

Choose a reason for hiding this comment

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

By if we end up needing to control aspects of dynamo model or view startup, do you mean a case where we'll need to check for feature flags at some point before the model is instantiated?

Copy link
Member Author

Choose a reason for hiding this comment

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

yes, and where we cannot recreate or reset that aspect of the model or view.

@mjkkirschner
Copy link
Member Author

one failure

MESSAGE:
TearDown : System.InvalidOperationException : No process is associated with this object.
+++++++++++++++++++
STACK TRACE:
--TearDown
   at System.Diagnostics.Process.EnsureState(State state)
   at System.Diagnostics.Process.EnsureState(State state)
   at System.Diagnostics.Process.GetProcessHandle(Int32 access, Boolean throwIfExited)
   at System.Diagnostics.Process.Kill()
   at Dynamo.Utilities.CLIWrapper.KillProcess() in c:\WorkspaceDynamo\src\DynamoUtilities\Md2Html.cs:line 77
   at Dynamo.Models.DynamoModel.Dispose() in c:\WorkspaceDynamo\src\DynamoCore\Models\DynamoModel.cs:line 1271
   at Dynamo.Models.DynamoModel.ShutDownCore(Boolean shutdownHost) in c:\WorkspaceDynamo\src\DynamoCore\Models\DynamoModel.cs:line 455
   at Dynamo.Models.DynamoModel.ShutDown(Boolean shutdownHost) in c:\WorkspaceDynamo\src\DynamoCore\Models\DynamoModel.cs:line 420
   at Dynamo.ViewModels.DynamoViewModel.PerformShutdownSequence(ShutdownParams shutdownParams) in c:\WorkspaceDynamo\src\DynamoCoreWpf\ViewModels\Core\DynamoViewModel.cs:line 2930
   at DynamoCoreWpfTests.DynamoTestUIBase.Exit() in c:\WorkspaceDynamo\test\DynamoCoreWpfTests\DynamoTestUIBase.cs:line 124
``` looking at it.

@mjkkirschner
Copy link
Member Author

Tests passed now, running master-15 serial tests as well. PTAL!

@mjkkirschner mjkkirschner added PTAL Please Take A Look 👀 and removed WIP labels Apr 21, 2022
@mjkkirschner mjkkirschner changed the title WIP wrap launch darkly in CLI to avoid bringing in new deps wrap launch darkly in CLI to avoid bringing in new deps Apr 21, 2022
{94CF053D-BB66-4FC7-883B-48F072701BA9}.Release|Any CPU.ActiveCfg = Release|Any CPU
{94CF053D-BB66-4FC7-883B-48F072701BA9}.Release|Any CPU.Build.0 = Release|Any CPU
{94CF053D-BB66-4FC7-883B-48F072701BA9}.Release|x64.ActiveCfg = Release|Any CPU
{94CF053D-BB66-4FC7-883B-48F072701BA9}.Release|x64.Build.0 = Release|Any CPU
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 want to build this tool by default ....with the rest of the solution ?

Copy link
Member Author

Choose a reason for hiding this comment

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

We do so for the other CLI tools, why wouldn't we?

Copy link
Contributor

Choose a reason for hiding this comment

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

I guess if the tool does not directly depend on any other Dynamo projects it may have a slower dev cycle than the rest.
But I guess it is a small project (few cs files) so it does not really slow down the build process that much

@@ -873,6 +905,28 @@ protected DynamoModel(IStartConfiguration config)
DynamoReady(new ReadyParams(this));
}

private void CheckFeatureFlagTest()
{
if (DynamoModel.FeatureFlags.CheckFeatureFlag<bool>("EasterEggIcon1", false))
Copy link
Contributor

Choose a reason for hiding this comment

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

we will need to store the possible feature flag names in some way (config file?) right ?

Copy link
Member Author

@mjkkirschner mjkkirschner Apr 21, 2022

Choose a reason for hiding this comment

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

why? To what end?

Copy link
Member Author

@mjkkirschner mjkkirschner Apr 21, 2022

Choose a reason for hiding this comment

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

I should mention that the keys, once created in launch darkly, are immutable. (besides being deletable)

Copy link
Contributor

Choose a reason for hiding this comment

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

In our discussions it seemed necessary to provide a way for feature flags to work offline (Like for ALIAS)
I may have misunderstood.
It is fine for now regardless.

src/Dynamo.All.sln Outdated Show resolved Hide resolved
</ImportGroup>
<PropertyGroup>
<OutputType>Exe</OutputType>
<OutputPath>$(OutputPath)\DynamoFeatureFlags\</OutputPath>
Copy link
Contributor

Choose a reason for hiding this comment

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

Remind me, the output will not be part of DynamoCore right?

Copy link
Member Author

@mjkkirschner mjkkirschner Apr 21, 2022

Choose a reason for hiding this comment

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

It will be placed in Bin\AnyCPU\{config}\DynamoFeatureFlags subfolder so it will be part of DynamoCoreRuntime release zip and artifactory build - but it won't pollute the root bin folder. The way this tool currently works, even sandbox users will have access to feature flags.

Copy link
Contributor

@pinzart90 pinzart90 left a comment

Choose a reason for hiding this comment

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

Some comments.
LGTM

Copy link
Contributor

@sm6srw sm6srw left a comment

Choose a reason for hiding this comment

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

LGTM!

@mjkkirschner mjkkirschner merged commit a24d3c1 into DynamoDS:master Apr 22, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
PTAL Please Take A Look 👀
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants