microsoft / AL

Home of the Dynamics 365 Business Central AL Language extension for Visual Studio Code. Used to track issues regarding the latest version of the AL compiler and developer tools available in the Visual Studio Code Marketplace or as part of the AL Developer Preview builds for Dynamics 365 Business Central.
MIT License
728 stars 241 forks source link

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

Closed ptrk-tr closed 5 months ago

ptrk-tr commented 8 months ago

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:

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

BazookaMusic commented 8 months ago

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

ptrk-tr commented 7 months ago

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 'xxx@yyy.de' 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 'xxx@yyy.de' 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.

thloke commented 5 months ago

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.

ptrk-tr commented 5 months ago

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.