Skip to content

Commit

Permalink
Synchronise access to shared table info dictionary (#101)
Browse files Browse the repository at this point in the history
  • Loading branch information
kilnerm committed Feb 12, 2019
1 parent c213e82 commit c448d1b
Showing 1 changed file with 16 additions and 9 deletions.
25 changes: 16 additions & 9 deletions Sources/SwiftKueryORM/TableInfo.swift
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ import Dispatch

public class TableInfo {
private var codableMap = [String: (info: TypeInfo, table: Table)]()
private var codableMapLock = DispatchSemaphore(value: 1)
private var codableMapQueue = DispatchQueue(label: "codableMap.queue", attributes: .concurrent)

/// Get the table for a model
func getTable<T: Decodable>(_ idColumn: (name: String, type: SQLDataType.Type), _ tableName: String, for type: T.Type) throws -> Table {
Expand All @@ -35,18 +35,25 @@ public class TableInfo {

func getInfo<T: Decodable>(_ idColumn: (name: String, type: SQLDataType.Type), _ tableName: String, _ type: T.Type) throws -> (info: TypeInfo, table: Table) {
let typeString = "\(type)"
if let result = codableMap[typeString] {
var result: (TypeInfo, Table)? = nil
// Read from codableMap when no concurrent write is occurring
codableMapQueue.sync {
result = codableMap[typeString]
}
if let result = result {
return result
}

codableMapLock.wait()
defer { codableMapLock.signal() }

let typeInfo = try TypeDecoder.decode(type)
let result = (info: typeInfo, table: try constructTable(idColumn, tableName, typeInfo))
codableMap[typeString] = result
try codableMapQueue.sync(flags: .barrier) {
let typeInfo = try TypeDecoder.decode(type)
result = (info: typeInfo, table: try constructTable(idColumn, tableName, typeInfo))
codableMap[typeString] = result
}

return result
guard let decodeResult = result else {
throw RequestError(.ormInternalError, reason: "Unable to decode Table info")
}
return decodeResult
}

/// Construct the table for a Model
Expand Down

0 comments on commit c448d1b

Please sign in to comment.