2016-09-16 2 views
3

Я знаю о компонентах и ​​системе (их еще не использовали), но я хотел бы знать, как инициализировать ресурс, когда метод init может запускаться из любого потока. Допустим, у нас есть 10 потоков, и все они используют db, и потоки могут начинаться в любом порядке. Как инициализировать пул подключений db в таком случае?Каков правильный способ инициализации ресурсов в многопоточной программе в Clojure

В настоящее время я использую сравнение и настроен для этого, но почему-то это не так. Это то, что я делаю.

(let [datasource (atom nil)] 
    (defn pooled-conn 
    "Get a Hikari pooled connection to the database. There will only be one 
    connection pool for the vm. Additional calls to this function will return 
    the same connection pool. The connection pool will be created by the first 
    call to this function" 
    [datasource-options] 
    (when (nil? @datasource) 
     (let [ds (make-datasource datasource-options)] 
     (when-not (compare-and-set! datasource nil {:datasource ds}) 
      (close-datasource ds)))) 
    @datasource)) 

Я не знаю, когда начинается виртуальная машина, только когда моя начинается нить (я использую шторм, дб пул инициализируется в некоторых болтах). Есть лучший способ сделать это?

+1

Вы упомянули компоненты и систему, вы также можете проверить [mount] (https://github.com/tolitius/mount) для более естественного ощущения clojure. – Shlomi

+0

Выглядит круто @ Шломи, проверит его – Ravi

ответ

3

Вы хотите использовать функцию locking. Это похоже на synchronized на Java.

Пожалуйста, смотрите полную документацию здесь: http://clojuredocs.org/clojure.core/locking

Вы код будет выглядеть следующим образом:

(def datasource (atom)) 
(locking datasource 
    (when (nil? @datasource)) 
    (reset! datasource (make-datasource datasource-options)))) 

Обратите внимание, что вы на самом деле не нужны карта внутри атома.

+0

Выглядит намного лучше. Спасибо! – Ravi

Смежные вопросы