Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

No exception being thrown when opening MySqlConnection?

Tags:

c#

mysql

I'm just starting out with async and Task's and my code has stopped processing. It happens when I have an incoming network packet and I try and communicate with the database inside the packet handler.

public class ClientConnectedPacket : IClientPacket
{
    private readonly EntityFactory _entityFactory;

    public ClientConnectedPacket(EntityFactory entityFactory)
    {
        _entityFactory= entityFactory;
    }

    public async Task Handle(NetworkClient client, ClientPacketReader reader)
    {
        client.Entity = await _entityFactory.CreateInstanceAsync( reader.GetValueByKey("unique_device_id"));

        // this Console.WriteLine never gets reached
        Console.WriteLine($"Client [{reader.GetValueByKey("unique_device_id")}] has connected");
    }
}

The Handle method gets called from an async task

if (_packetRepository.TryGetPacketByName(packetName, out var packet))
{
    await packet.Handle(this, new ClientPacketReader(packetName, packetData));
}
else
{
    Console.WriteLine("Unknown packet: " + packetName);
}

Here is the method which I think is causing the issue

public async Task<Entity> CreateInstanceAsync(string uniqueId)
{
    await using (var dbConnection = _databaseProvider.GetConnection())
    { 
        dbConnection.SetQuery("SELECT COUNT(NULL) FROM `entities` WHERE `unique_id` = @uniqueId");
        dbConnection.AddParameter("uniqueId", uniqueId);

        var row = await dbConnection.ExecuteRowAsync();

        if (row != null)
        {
            return new Entity(uniqueId, false);
        }
    }

    return new Entity(uniqueId,true);
}

DatabaseProvider's GetConnection method:

public DatabaseConnection GetConnection()
{
    var connection = new MySqlConnection(_connectionString);
    var command = connection.CreateCommand();

    return new DatabaseConnection(_logFactory.GetLogger(), connection, command);
}

DatabaseConnection's constructor:

public DatabaseConnection(ILogger logger, MySqlConnection connection, MySqlCommand command)
{
    _logger = logger;

    _connection = connection;    
    _command = command;

    _connection.Open();
}

When I comment out this line, it reaches the Console.WriteLine

_connection.Open();
like image 861
AAA Avatar asked Apr 07 '20 13:04

AAA


1 Answers

I ran a POC project spinning 100 parallel tasks both with MySql.Data 8.0.19 and MySqlConnector 0.63.2 on .NET Core 3.1 console application. I create, open and dispose the connection into the context of every single task. Both providers runs to completion without errors.

The specifics are that MySql.Data queries run synchronously although the library provide async methods signature e.g. ExecuteReaderAsync() or ExecuteScalarAsync(), while MySqlConnector run truly asynchronously.

You may be running into:

  • a deadlock situation not specifically related to the mysql provider
  • not properly handling exceptions inside your tasks (you may inspect the task associated aggregate exception and also monitor mysql db logs)
  • you execution be still blocked (not returning result) when you assume it’s not working, if you running a high number of parallel tasks with MySql.Data as it executes synchronously
like image 137
kalitsov Avatar answered Nov 15 '22 07:11

kalitsov