簡體   English   中英

函數式編程中的線程資源(如連接)方法

[英]Approach to thread resources like connections in functional programming

假設您需要連接到數據庫。

因此,您將DbConnection作為某種假設函數的最后一個參數,其類型如下: doDbStuff :: Int -> DbConnection -> Int

也許還有其他函數也依賴於DbConnection ,並且所有這些函數都在執行寫操作。 因此,它們可以單獨運行,也可以作為原子操作(即事務 )的一部分運行。

由於可能要使用一個來管理DbConnection ,並且功能可能是原子操作的一部分,也可能不是原子操作的一部分,因此這些函數未實現從池中獲取DbConnection實例以及將其釋放到池中的代碼。

現在,這些功能是長功能組合的一部分,某些決定可能涉及這些功能,不需要DbConnection 也就是說,有可能從池中獲取DbConnection並將其用於另一個請求,這可能會產生瓶頸。

還有一種選擇,即不注入DbConnection而是注入高階函數,如withConnection :: (DbConnection -> a) -> a ,因此每個函數都可以使用DbConnection ,使用它,整個withConnection負責獲取和釋放連接。 這里的缺點是,作為原子操作的一部分,很難使許多功能進行協作。

所以...

目前,我一直在使用#2方法。 順便說一句,是否有任何其他方法可以保留兩種方法中的最佳方法?

JavaScript中的偽代碼:

方法1

const connectionString = '[whatever]'
const env = { connection: acquire (connectionString) }

const output = composition (arg0) (argN) (env)
// then, release the connection

// f :: a -> b -> { connection: DbConnection }
const f = x => y => ({ connection }) => 
    doDbStuff (x + y) (connection)

方法#2

const withConnection = f => [stuff to acquire the connection, and aftewards, release it]
const env = { withConnection }

const output = composition (arg0) (argN) (env)

// type FnConnection DbConnection c = c -> a
// f :: a -> a -> { connection: FnConnection }
const f = x => y => ({ withConnection }) => 
    withConnection (doDbStuff (x + y))

有一種針對這種情況的工具,您的解決方案非常接近! 讀者adt允許您在訪問某些環境的情況下編寫函數。 這是我最喜歡的實現: https : //github.com/monet/monet.js/blob/master/docs/READER.md

不幸的是,此模式可能需要將大量代碼包裝在閱讀器類型中-但是您已經引入了withConnection包裝器,這導致幾乎相同數量的額外代碼。

這是一個示例,該示例從數據庫中讀取ID為“ 123”的文檔,覆蓋某些屬性,然后將結果寫回到數據庫中。 直到實際運行程序時才提供db連接,但是您可以編寫代碼,前提是在運行代碼時將存在db連接。

const { Reader } = require('monet');

const findById = (id) => Reader(({ db }) => db.find({ id }));
const insertDoc = (doc) => Reader(({ db }) => db.insert(doc));
const copyWithDefaults = (doc) => ({
    ...doc,
    name: 'default name',
});

const app =
    findById('123')
        .map(copyWithDefaults)
        .chain(insertDoc)

app.run({ db: aquire(connectionString) })

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM