AL icon indicating copy to clipboard operation
AL copied to clipboard

BC23 OnPrem - Publishing app w/ large file and .NET declaration in same file takes a long time

Open ptrk-tr opened this issue 2 years ago • 2 comments

Heya, not sure if this is a compiler issue or something else, just wanted to post it somewhere, if it's wrong in this Repo, then kindly pass it on to the correct team and close the issue, thanks.

Happy to provide more info on this, if needed.


Please include the following with each issue:

1. Describe the bug Publishing an app in BC 23.1 from VS Code that contains a large file and a dotnet declaration in the same file as shown below takes a long time. In my test case the app had a codeunit with >10.000 lines of code and the following dotnet declaration on top.

dotnet
{
    assembly(Microsoft.Data.SqlClient)
    {
        Culture = 'neutral';
        PublicKeyToken = '23ec7fc2d6eaa4a5';
        Version = '5.0.0.0';

        type(Microsoft.Data.SqlClient.SqlDataAdapter; DotNetSQLDataAdapter) { }
        type(Microsoft.Data.SqlClient.SqlCommand; DotNetSQLCommand) { }
        type(Microsoft.Data.SqlClient.SqlConnection; DotNetSqlConnection) { }
        type(Microsoft.Data.SqlClient.SqlDataReader; DotNetSqlDataReader) { }
        type(Microsoft.Data.SqlClient.SqlParameter; DotNetSqlParameter) { }
    }
}

Publishing this particular app took 18 minutes every time I tried publishing via VS Code. Seperating the dotnet part into its own file (and cutting down on some code to get to roughly 9.000 lines of code) reduced the publishing time to <1 minute.

2. To Reproduce Steps to reproduce the behavior:

  1. Create a new app with target OnPrem.
  2. Create Codeunit with a procedure that has roughly 10.000 lines of code, like 10.000 lines of Sleep(0).
  3. Publish the app. (Should be done in seconds).
  4. Add the dotnet part on top of the file and publish again (add the 230 Service path to assembly probing paths to get the Microsoft.Data.SqlClient DLL working).
  5. Publishing takes longer (in my case ~3 minutes, with just one codeunit with 10.000 lines of Sleep(0) in a procedure).
dotnet
{
    assembly(Microsoft.Data.SqlClient)
    {
        Culture = 'neutral';
        PublicKeyToken = '23ec7fc2d6eaa4a5';
        Version = '5.0.0.0';

        type(Microsoft.Data.SqlClient.SqlDataAdapter; DotNetSQLDataAdapter) { }
        type(Microsoft.Data.SqlClient.SqlCommand; DotNetSQLCommand) { }
        type(Microsoft.Data.SqlClient.SqlConnection; DotNetSqlConnection) { }
        type(Microsoft.Data.SqlClient.SqlDataReader; DotNetSqlDataReader) { }
        type(Microsoft.Data.SqlClient.SqlParameter; DotNetSqlParameter) { }
    }
}

codeunit 50100 "Sleepy Codeunit"
{
    procedure PretendSleeping()
    begin
        Sleep(0);
        Sleep(0);
        Sleep(0);
        Sleep(0);
        Sleep(0);
        .
        .
        .(add another 10.000 lines)
    end;
}

Note: Because the developers need to copy and paste the code snippet, including a code snippet as a media file (i.e. .gif) is not sufficient.

3. Expected behavior Publishing finishes in a timely matter.

4. Actual behavior Publishing the app takes way longer than it previously did in BC 22. In my case 18 minutes on every publish.

5. Versions:

  • AL Language: v13.0.903630
  • Visual Studio Code: 1.85.1
  • Business Central: 23.1 DE OnPrem
  • List of Visual Studio Code extensions that you have installed:

andrzejzwierzchowski.al-code-outline argutec.argutec-azure-repos daniel-nt.al-translation-center davidfeldhoff.al-codeactions eamodio.gitlens ms-dynamics-smb.al ms-graph.kiota ms-vscode.azure-repos ms-vscode.powershell statical.prism-al usernamehw.errorlens vector-of-bool.gitflow

ptrk-tr avatar Dec 27 '23 16:12 ptrk-tr

Very intriguing bug, it could affect other cases as well, so with a clear repro it's worth looking at

BazookaMusic avatar Dec 29 '23 10:12 BazookaMusic

I went ahead and created a simple 2 App workspace project to help repro this issue. It contains a simple Codeunit in each app, one with the DotNet declaration on top of it, one with the DotNet declaration in a seperate dotnet.al file. You should be able to pull this from here: https://github.com/ptrk-tr/AL-Issue-7627

Publishing these two apps to my locally installed 23.1 BC DE OnPrem environment gives me these results when publishing:

DotNet in same file took more than 5 minutes to publish):

[2023-12-30 13:51:07.44] Publishing AL application using launch configuration 'BC230'.
[2023-12-30 13:51:07.88] Authenticated as user '[email protected]' in tenant 'xxxxxxxxxxx'. Please note that these credentials are cached. Clear the credentials cache to authenticate as another user.
[2023-12-30 13:51:07.88] Targeting Dynamics 365 Business Central.
[2023-12-30 13:51:07.89] Sending request to http://xxxxx:7049/BC230/dev/apps?SchemaUpdateMode=forcesync&DependencyPublishingOption=default
[2023-12-30 13:56:47.71] Success: The package 'Default Publisher_DotNet Declaration in large file_1.0.0.0.app' has been published to the server.

DotNet in speprate file took roughly 14 seconds to publish:

[2023-12-30 13:50:30.68] Publishing AL application using launch configuration 'BC230'.
[2023-12-30 13:50:31.12] Authenticated as user '[email protected]' in tenant 'xxxxxxxxxxx'. Please note that these credentials are cached. Clear the credentials cache to authenticate as another user.
[2023-12-30 13:50:31.12] Targeting Dynamics 365 Business Central.
[2023-12-30 13:50:31.13] Sending request to http://xxxxx:7049/BC230/dev/metadata
[2023-12-30 13:50:31.29] Sending request to http://xxxxx:7049/BC230/dev/apps?SchemaUpdateMode=forcesync&DependencyPublishingOption=default
[2023-12-30 13:50:45.28] Success: The package 'Default Publisher_DotNet Declaration in seperate file_1.0.0.0.app' has been published to the server.

The environment is set up with Entra ID authentication, didn't have any other dev environment at hand so I couldn't check the issue with other auth types.

Ping me if theres any more information you need, happy to provide in that case.

ptrk-tr avatar Dec 30 '23 13:12 ptrk-tr

I've looked into this, and it's quite interesting. This actually happens whenever you have two objects in the same .al file, that one of them is a DotNet object doesn't matter. It can be two codeunits and you'll run into the same problem as well. As long as one (or both) are large objects, the time it takes to compile the .al file increases significantly.

The reason for this is a bit complicated and is to do with how we map statements in the compiled AL code artefacts to the source AL code. This is required so that when a breakpoint is set during a debugging session, we know how to map the source AL line where the breakpoint is set to the actual executed code on the server.

Changing this is very risky (it can break debugging if we get this wrong), and the workaround is simple. If you have a large object, separate it out into its own file.

Therefore, we're not going to fix it at this time. The risk/reward calculation doesn't work out. But thanks for raising this, the investigation was interesting and fun.

thloke avatar Mar 15 '24 06:03 thloke

Thanks for looking into this, the explanation is very interesting to read. Glad you had fun investigating this and I agree, the workaround is simple and I'm fine with this not getting further attention.

ptrk-tr avatar Mar 15 '24 09:03 ptrk-tr