Swift3 swift在perfect中是否有db连接池?

Swift3 swift在perfect中是否有db连接池?,swift3,perfect,Swift3,Perfect,我正在寻找一个完美的swift 3或以上的数据库连接池包装。我找不到任何通过搜索,所以我决定问是否有人可以提供一个提示 提前感谢我宁愿说是高效的重复使用连接,而不是池。以完美MySQL为例: import MySQL import PerfectThread #if os(Linux) import Glibc #else import Darwin #endif let mysql = MySQL() let lock = Threading.Lock() var jobs = 10 fu

我正在寻找一个完美的swift 3或以上的数据库连接池包装。我找不到任何通过搜索,所以我决定问是否有人可以提供一个提示


提前感谢

我宁愿说是高效的重复使用连接,而不是池。以完美MySQL为例:

import MySQL
import PerfectThread
#if os(Linux)
import Glibc
#else
import Darwin
#endif

let mysql = MySQL()
let lock = Threading.Lock()
var jobs = 10

func now(_ id: Int) {
  print("Job Now #", id)
  lock.doWithLock {
    let x = mysql.query(statement: "SELECT now() as time")
    guard x, let y = mysql.storeResults(),
    let row = y.next() else {
      print(mysql.errorMessage())
      return
    }
    print(row[0] ?? "Now() FAILED")
    y.close()
    jobs -= 1
  }
}

func user(_ id: Int) {
  print("Job Usr #", id)
  lock.doWithLock {
    let x = mysql.query(statement: "select User from user")
    guard x, let y = mysql.storeResults(),
      let row = y.next() else {
       print(mysql.errorMessage())
       return
   }
    print(row[0] ?? "User() FAILED")
    y.close()
    jobs -= 1
  }
}

_ = mysql.setOption(.MYSQL_SET_CHARSET_NAME, "utf8mb4")
guard mysql.connect(host: "127.0.0.1", user: "root", password: "your pass", db: "mysql") else {
  print(mysql.errorMessage())
  exit(0)
}

jobs = 10
for id in 0 ..< 5 {
  Threading.dispatch {
    now(id)
  }
  Threading.dispatch {
    user(id)
  }
}

while jobs > 0 {
  sleep(1)
}
通过使用Threading.Lock,您可以轻松地将所有查询排队到一个连接中,并最大限度地提高效率—快速、原子、有序、共享和单例

如果坚持,您可以创建到阵列的有限数量的连接,并且每个连接保持一个锁以实现平衡,比如说,线程连接池,因此我相信这种平衡解决方案可以在Perfect本身上建立,而无需任何特殊模块:

struct MySQLPool {
  let mysql = MySQL()
  let lock = Threading.Lock()
 }
var pool: [MySQLPool] = []
for _ in 0 ..< 32 {
  pool.append(YourNewConnection)
}

我根据@PerfectlyRock答案的最后一部分实现了一个简单的池机制,请查看:

import PerfectMySQL
import Foundation
import PerfectThread
#if os(Linux)
import Glibc
#else
import Darwin
#endif

class DBManager {

struct MySQLPoolItem {
    let mysql = MySQL()
    let lock = Threading.Lock()
    func connect()->Bool{
        return mysql.connect(host: Prefs.dbhost, user: Prefs.dbuser, password: Prefs.dbpass, db: Prefs.schema)
    }
}

var pool: [MySQLPoolItem] = []

static let shared = DBManager()

func preparePool() {

    var connectionCount = Prefs.connectionPoolCount

    while connectionCount > 0 {

        let item = MySQLPoolItem()
        _ = item.mysql.setOption(.MYSQL_SET_CHARSET_NAME, "utf8")
        let connected = item.connect()
        guard connected else {
            // verify we connected successfully
            print(item.mysql.errorMessage())
            return
        }
        print("Database connection \((connectionCount)) success");
        pool.append(item)
        connectionCount -= 1
    }

}

func getAvailableConnection() -> MySQLPoolItem {

    var item : MySQLPoolItem? = nil;

    while item == nil {
        item = tryAvailableConnection()
        if(item == nil){
            sleep(1)
        }
    }

    return item!
}

private func tryAvailableConnection() -> MySQLPoolItem? {

    for item in pool {

        if(item.lock.tryLock()){

            if(!item.mysql.ping()){
                if(item.connect()){
                    return item
                }
                item.lock.unlock()
            }else{
                return item
            }

        }

    }

    return nil

}

func runSync(query: String) -> ((result:Bool,items:MySQL.Results?)) {

    let poolItem = getAvailableConnection()

    defer {
        poolItem.lock.unlock()
    }

    let querySuccess = poolItem.mysql.query(statement: query)

    return (querySuccess,poolItem.mysql.storeResults())

}

}

谢谢你的回答