1 /** 2 * Модуль подключения к базе данных 3 * 4 * Copyright: (c) 2015-2017, Milofon Project. 5 * License: Subject to the terms of the BSD license, as written in the included LICENSE.txt file. 6 * Authors: Maksim Galanin 7 */ 8 module dango.system.database.pool; 9 10 private 11 { 12 import std.container : SList; 13 14 import vibe.core.sync; 15 import vibe.core.core : Mutex; 16 } 17 18 19 /** 20 * Интерфейс объекта с возможностью хранения в пуле 21 */ 22 interface Connection 23 { 24 bool connected() @property; 25 26 void connect(); 27 28 void disconnect(); 29 } 30 31 32 /** 33 * Интерфейс пула 34 */ 35 interface ConnectionPool(C) 36 { 37 /** 38 * Получить подключение из пула 39 */ 40 C connection() @safe; 41 42 /** 43 * Вернуть подключение в пул 44 * Params: 45 * 46 * conn = Освобождаемое подключение 47 */ 48 void freeConnection(C conn) @safe; 49 50 /** 51 * Создание нового подключения 52 */ 53 C createNewConnection(); 54 } 55 56 57 abstract class BaseConnectionPool(C) : ConnectionPool!C 58 { 59 private 60 { 61 SList!C _pool; 62 Mutex _mutex; 63 TaskCondition _condition; 64 uint _size; 65 } 66 67 68 this(uint size) 69 { 70 _mutex = new Mutex(); 71 _condition = new TaskCondition(_mutex); 72 _size = size; 73 initializePool(); 74 } 75 76 77 /** 78 * Получить подключение из пула 79 */ 80 C connection() @safe 81 { 82 _mutex.lock(); 83 while (_pool.empty) 84 _condition.wait(); 85 86 auto conn = () @trusted { 87 auto conn = _pool.front(); 88 if (!conn.connected) 89 conn.connect(); 90 return conn; 91 } (); 92 93 _pool.removeFront(); 94 _mutex.unlock(); 95 return conn; 96 } 97 98 /** 99 * Вернуть подключение в пул 100 * Params: 101 * 102 * conn = Освобождаемое подключение 103 */ 104 void freeConnection(C conn) @safe 105 { 106 _mutex.lock(); 107 _pool.insertFront(conn); 108 _condition.notify(); 109 _mutex.unlock(); 110 } 111 112 113 private void initializePool() 114 { 115 _mutex.lock(); 116 foreach (i; 0.._size) 117 _pool.insertFront(createNewConnection()); 118 _mutex.unlock(); 119 } 120 }