ConnectionPool.cs 2.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  1. using System;
  2. using System.Collections.Concurrent;
  3. using SQLitePCL.pretty;
  4. namespace Emby.Server.Implementations.Data;
  5. /// <summary>
  6. /// A pool of SQLite Database connections.
  7. /// </summary>
  8. public sealed class ConnectionPool : IDisposable
  9. {
  10. private readonly BlockingCollection<SQLiteDatabaseConnection> _connections = new();
  11. private bool _disposed;
  12. /// <summary>
  13. /// Initializes a new instance of the <see cref="ConnectionPool" /> class.
  14. /// </summary>
  15. /// <param name="count">The number of database connection to create.</param>
  16. /// <param name="factory">Factory function to create the database connections.</param>
  17. public ConnectionPool(int count, Func<SQLiteDatabaseConnection> factory)
  18. {
  19. for (int i = 0; i < count; i++)
  20. {
  21. _connections.Add(factory.Invoke());
  22. }
  23. }
  24. /// <summary>
  25. /// Gets a database connection from the pool if one is available, otherwise blocks.
  26. /// </summary>
  27. /// <returns>A database connection.</returns>
  28. public ManagedConnection GetConnection()
  29. {
  30. if (_disposed)
  31. {
  32. ThrowObjectDisposedException();
  33. }
  34. return new ManagedConnection(_connections.Take(), this);
  35. static void ThrowObjectDisposedException()
  36. {
  37. throw new ObjectDisposedException(nameof(ConnectionPool));
  38. }
  39. }
  40. /// <summary>
  41. /// Return a database connection to the pool.
  42. /// </summary>
  43. /// <param name="connection">The database connection to return.</param>
  44. public void Return(SQLiteDatabaseConnection connection)
  45. {
  46. if (_disposed)
  47. {
  48. connection.Dispose();
  49. return;
  50. }
  51. _connections.Add(connection);
  52. }
  53. /// <inheritdoc />
  54. public void Dispose()
  55. {
  56. if (_disposed)
  57. {
  58. return;
  59. }
  60. foreach (var connection in _connections)
  61. {
  62. connection.Dispose();
  63. }
  64. _connections.Dispose();
  65. _disposed = true;
  66. }
  67. }