beamable / BeamableProduct

The beamable product suite including com.beamable, com.beamable.server, microservice base image, portal, the installer, and build scripts
Other
7 stars 2 forks source link

Microservice Deploy Bug #3952

Open mhijaziB opened 1 month ago

mhijaziB commented 1 month ago

Describe the Bug

The bug is currently happening with Mythical on TWO projects when deploying multiple microservices. When dotnet beam deploy release is executed, some standalone microservices randomly fail with the following error:

**> -error CS2012: Cannot open '/Users/andresgutierrez/fifa-gameserver/microservices/services/fifa/obj/Release/net8.0/fifa.dll' for writing -- 'The process cannot access the file

'/Users/andresgutierrez/fifa-gameserver/microservices/services/fifa/obj/Release/net8.0/fifa.dll' because it is being used by another process.’ fifa.dll is one of the storages.**

It looks like the microservices are competing to generate this DLL, causing others to fail if they can’t read the compiled version. The error happens with other shared dlls as well.

To Reproduce

Steps to reproduce the behavior:

Expected Behavior

Actual Behavior

Screenshots

If applicable, add screenshots to help explain your problem.

Metadata

Additional Context

Mythical currently have a workaround where they run the builds sequentially to avoid the above error and here is their cli patch for it:


Subject: [PATCH] Add option to build microservices sequentially (not in
 parallel) --sequential-build or --seq-build

---
 cli/cli/Commands/DeploymentCommands/DeployArgs.cs        | 5 ++++-
 .../Commands/DeploymentCommands/PlanDeploymentCommand.cs | 4 ++++
 .../DeploymentCommands/ReleaseDeploymentCommand.cs       | 1 +
 cli/cli/Services/DeploymentService.cs                    | 9 +++++++--
 4 files changed, 16 insertions(+), 3 deletions(-)

diff --git a/cli/cli/Commands/DeploymentCommands/DeployArgs.cs b/cli/cli/Commands/DeploymentCommands/DeployArgs.cs
index 04fd0ad60..49da2313e 100644
--- a/cli/cli/Commands/DeploymentCommands/DeployArgs.cs
+++ b/cli/cli/Commands/DeploymentCommands/DeployArgs.cs
@@ -37,7 +37,10 @@ public class DeployArgs

        command.AddOption(new Option<bool>(new string[] { "--restart", "--redeploy", "--roll" }, "Restart existing deployed services"),
            (args, i) => args.UseLatestDeployedManifest = i);
-       
+
+       command.AddOption(new Option<bool>(new string[] { "--sequential-build", "--seq-build" }, "Sequential microservice build (no parallel)"),
+           (args, i) => args.SequentialBuild = i);
+
        AddModeOption(command, (args, i) => args.DeployMode = i);
    }

diff --git a/cli/cli/Commands/DeploymentCommands/PlanDeploymentCommand.cs b/cli/cli/Commands/DeploymentCommands/PlanDeploymentCommand.cs
index 362fc3ddb..576a2d95e 100644
--- a/cli/cli/Commands/DeploymentCommands/PlanDeploymentCommand.cs
+++ b/cli/cli/Commands/DeploymentCommands/PlanDeploymentCommand.cs
@@ -19,6 +19,8 @@ public interface IHasDeployPlanArgs
    public bool UseLatestDeployedManifest { get; set; }
    public DeployMode DeployMode { get; set; }
    public bool RunHealthChecks { get; set; }
+
+   public bool SequentialBuild { get; set; }
 }

 public class PlanDeploymentCommandArgs : CommandArgs, IHasDeployPlanArgs
@@ -31,6 +33,8 @@ public class PlanDeploymentCommandArgs : CommandArgs, IHasDeployPlanArgs
    public bool UseLatestDeployedManifest { get; set; }
    public DeployMode DeployMode { get; set; }
    public bool RunHealthChecks { get; set; }
+
+   public bool SequentialBuild { get; set; }
 }

 public class PlanReleaseProgressChannel : IResultChannel
diff --git a/cli/cli/Commands/DeploymentCommands/ReleaseDeploymentCommand.cs b/cli/cli/Commands/DeploymentCommands/ReleaseDeploymentCommand.cs
index 98e0993ed..5317032d2 100644
--- a/cli/cli/Commands/DeploymentCommands/ReleaseDeploymentCommand.cs
+++ b/cli/cli/Commands/DeploymentCommands/ReleaseDeploymentCommand.cs
@@ -21,6 +21,7 @@ public class ReleaseDeploymentCommandArgs : CommandArgs, IHasDeployPlanArgs
    public bool UseLatestDeployedManifest { get; set; }
    public DeployMode DeployMode { get; set; }
    public bool RunHealthChecks { get; set; }
+   public bool SequentialBuild { get; set; }
 }

diff --git a/cli/cli/Services/DeploymentService.cs b/cli/cli/Services/DeploymentService.cs
index 9da5bdef0..348b46b01 100644
--- a/cli/cli/Services/DeploymentService.cs
+++ b/cli/cli/Services/DeploymentService.cs
@@ -890,7 +890,7 @@ public partial class DeployUtil
        }
        else
        {
-           localTask = CreateReleaseManifestFromLocal(provider, beamo.BeamoManifest, progressHandler);
+           localTask = CreateReleaseManifestFromLocal(provider, beamo.BeamoManifest, progressHandler, args.SequentialBuild);
        }
        progressHandler?.Invoke(MergingManifestProgressName, 0);

@@ -1224,7 +1224,7 @@ public partial class DeployUtil
        return (localManifest, new List<BuildImageOutput>());
    }

-   public static async Task<(ManifestView, List<BuildImageOutput>)> CreateReleaseManifestFromLocal(IDependencyProvider provider, BeamoLocalManifest localManifest, ProgressHandler progressHandler)
+   public static async Task<(ManifestView, List<BuildImageOutput>)> CreateReleaseManifestFromLocal(IDependencyProvider provider, BeamoLocalManifest localManifest, ProgressHandler progressHandler, bool sequentialBuild)
    {
        var services = new ServiceReference[localManifest.HttpMicroserviceLocalProtocols.Count];
        var storages = new ServiceStorageReference[localManifest.EmbeddedMongoDbLocalProtocols.Count];
@@ -1264,6 +1264,11 @@ public partial class DeployUtil
                        }
                    });
                    pendingTasks.Add(task);
+
+                   if (sequentialBuild)
+                   {
+                       task.Wait();
+                   }
                    break;
                case BeamoProtocolType.EmbeddedMongoDb:
                    storages[storageIndex++] = CreateStorageReference(
-- 
2.46.0.windows.1
cdhanna commented 1 month ago

I'm working on this; some fixes went out in CLI 4.1.5; but they weren't working on Windows. I'm researching replacing our project build sequence with a single solution level build pass.