dotnet / linker

389 stars 127 forks source link

Blazor webassembly gives a linker error when using Microsoft.Azure.CosmosDB.BulkExecutor #1425

Open agocke opened 4 years ago

agocke commented 4 years ago

Describe the bug

Blazor webassembly gives a linker error when using Microsoft.Azure.CosmosDB.BulkExecutor. The error is Unhandled exception. Mono.Linker.MarkException: Error processing method: 'System.Void Microsoft.Azure.CosmosDB.BulkExecutor.MongoBulkExecutor::.ctor(System.Uri,System.String,System.String,System.String,Microsoft.Azure.Documents.Client.ConnectionPolicy,System.Nullable`1,Newtonsoft.Json.JsonSerializerSettings)' in assembly: 'Microsoft.Azure.CosmosDB.BulkExecutor.dll' BlazorWebSite

To Reproduce

create a blazor webassembly project and reference Microsoft.Azure.CosmosDB.BulkExecutor

add some code such as:

 public async void CreateItemsAsync(T[] item)
        {
            ConnectionPolicy ConnectionPolicy = new ConnectionPolicy
            {
                ConnectionMode = ConnectionMode.Direct,
                ConnectionProtocol = Protocol.Tcp
            };

            using (var client = new DocumentClient(new Uri(Endpoint), Key, ConnectionPolicy))
            {
                // Set retry options high during initialization (default values).
                client.ConnectionPolicy.RetryOptions.MaxRetryWaitTimeInSeconds = 30;
                client.ConnectionPolicy.RetryOptions.MaxRetryAttemptsOnThrottledRequests = 9;

                DocumentCollection dataCollection = GetCollectionIfExists(client, DatabaseId, CollectionId);
                IBulkExecutor bulkExecutor = new BulkExecutor(client, dataCollection);
                await bulkExecutor.InitializeAsync();

                // Set retries to 0 to pass complete control to bulk executor.
                client.ConnectionPolicy.RetryOptions.MaxRetryWaitTimeInSeconds = 0;
                client.ConnectionPolicy.RetryOptions.MaxRetryAttemptsOnThrottledRequests = 0;

                BulkImportResponse bulkImportResponse = null;
                long totalNumberOfDocumentsInserted = 0;
                double totalRequestUnitsConsumed = 0;
                double totalTimeTakenSec = 0;

                long numberOfDocumentsToGenerate = item.Length;
                long numberOfDocumentsPerBatch = 100;
                int numberOfBatches = (int)Math.Ceiling(((double)numberOfDocumentsToGenerate) / numberOfDocumentsPerBatch);

                var tokenSource = new CancellationTokenSource();
                var token = tokenSource.Token;
                var documentNumber = 0;

                for (int i = 0; i < numberOfBatches; i++)
                {
                    // Generate JSON-serialized documents to import.

                    List<string> documentsToImportInBatch = new List<string>();
                    long prefix = i * numberOfDocumentsPerBatch;

                    Trace.TraceInformation(String.Format("Generating {0} documents to import for batch {1}", numberOfDocumentsPerBatch, i));
                    for (int j = 0; j < numberOfDocumentsPerBatch; j++)
                    {
                        if (documentNumber < item.Length)
                            documentsToImportInBatch.Add(item[documentNumber++].ToString());
                    }

                    // Invoke bulk import API.

                    var tasks = new List<Task>
                    {
                        Task.Run(async () =>
                        {
                            Trace.TraceInformation(String.Format("Executing bulk import for batch {0}", i));
                            do
                            {
                                try
                                {
                                    bulkImportResponse = await bulkExecutor.BulkImportAsync(
                                        documents: documentsToImportInBatch,
                                        enableUpsert: false,
                                        disableAutomaticIdGeneration: true,
                                        maxConcurrencyPerPartitionKeyRange: null,
                                        maxInMemorySortingBatchSize: null,
                                        cancellationToken: token);
                                }
                                catch (DocumentClientException de)
                                {
                                    Trace.TraceError("Document client exception: {0}", de);
                                    break;
                                }
                                catch (Exception e)
                                {
                                    Trace.TraceError("Exception: {0}", e);
                                    break;
                                }
                            } while (bulkImportResponse.NumberOfDocumentsImported < documentsToImportInBatch.Count);

                            Trace.WriteLine(String.Format("\nSummary for batch {0}:", i));
                            Trace.WriteLine("--------------------------------------------------------------------- ");
                            Trace.WriteLine(String.Format("Inserted {0} docs @ {1} writes/s, {2} RU/s in {3} sec",
                                bulkImportResponse.NumberOfDocumentsImported,
                                Math.Round(bulkImportResponse.NumberOfDocumentsImported / bulkImportResponse.TotalTimeTaken.TotalSeconds),
                                Math.Round(bulkImportResponse.TotalRequestUnitsConsumed / bulkImportResponse.TotalTimeTaken.TotalSeconds),
                                bulkImportResponse.TotalTimeTaken.TotalSeconds));
                            Trace.WriteLine(String.Format("Average RU consumption per document: {0}",
                                (bulkImportResponse.TotalRequestUnitsConsumed / bulkImportResponse.NumberOfDocumentsImported)));
                            Trace.WriteLine("---------------------------------------------------------------------\n ");

                            totalNumberOfDocumentsInserted += bulkImportResponse.NumberOfDocumentsImported;
                            totalRequestUnitsConsumed += bulkImportResponse.TotalRequestUnitsConsumed;
                            totalTimeTakenSec += bulkImportResponse.TotalTimeTaken.TotalSeconds;
                        },
                    token)
                    };

                    await Task.WhenAll(tasks);
                }

            }

        }

upon build the error will show up along with

ILLink failed with exit code -532462766

Further technical details

netstandard2.1 3.0
agocke commented 4 years ago

Ported from https://github.com/dotnet/runtime/issues/40453