アトミック変更ログとして使用するには、データ構造に関するアドバイスが必要です。変更ログとしてのSTMにやさしいリスト
私は次のアルゴリズムを実装しようとしています。メモリ内のマップを更新するために入ってくる の変更の流れがあります。 Haskellのような擬似コードでは、DataSetがマップされ
update :: DataSet -> SomeListOf Change -> Change -> STM (DataSet, SomeListOf Change)
update dataSet existingChanges newChange = do
...
return (dataSet, existingChanges ++ [newChange])
(現在はそれがSTM-コンテナパッケージから地図、https://hackage.haskell.org/package/stm-containers-0.2.10/docs/STMContainers-Map.htmlである)です。 「更新」全体は任意の数のスレッドから呼び出されます。ドメインセマンティクスのために変更の一部が拒否される可能性があるため、トランザクションの影響を排除するためにthrowSTMを使用します。成功したコミットの場合、 "newChange"がリストに追加されます。この関数は変化する(それが一致ペアに有している)のリストと共に、データセットの現在のスナップショットを取り、それをフラッシュすることになっている
flush :: STM (DataSet, SomeListOf Change) -> IO()
:
は、以下の関数を呼び出す別のスレッドが存在します
flush data = do
(dataSet, changes) <- atomically $ readTVar data_
-- write them both to FS
-- ...
atomically $ writeTVar data_ (dataSet, [])
"SomeListOf Change"に使用するデータ構造についての助言が必要です。私は[あまりにも注文されている]ため、[変更]を使用したくないし、あまりにも多くの競合があり、トランザクション全体を再試行することが懸念される。私がここで間違っているなら、私を修正してください。
私はまだオーダーを保存する必要があるため、セット(https://hackage.haskell.org/package/stm-containers-0.2.10/docs/STMContainers-Set.html)を使用できません。トランザクションの順序がコミットされます。私はTChanを使用することができますが、それは良い一致(トランザクションのコミットの順番)のように見えますが、 "flush"関数を実装する方法がわからないので、変更ログ全体を一貫して見ることができますDataSetを使用します。
現在の実装は、applyActionsToState関数とrrdpSyncThread関数でそれぞれhttps://github.com/lolepezy/rpki-pub-server/blob/add-storage/src/RRDP/Repo.hsです。それはTChanを使用し、間違った方法でそれを行うようです。
ありがとうございます。
更新:合理的な答えはその
type SomeListOf c = TChan [c]
update :: DataSet -> TChan [Change] -> Change -> STM DataSet
update dataSet existingChanges newChange = do
...
writeTChan changeChan $ reverse (newChange : existingChanges)
return dataSet
flush data_ = do
(dataSet, changes) <- atomically $ (,) <$> readTVar data_ <*> readTChan changeChan
-- write them both to FS
-- ...
のようであるように思わしかし、私はまだそれがチャネルの要素として、リスト全体を渡すためにきちんとした解決策のかどうかわかりません。
私はあなたの質問を慎重に読んでいませんでしたが、 'TChan'はデッドシンプルな'([a]、[a]) 'デキューです。あなた自身のバリエーションを実装することが理にかなっているように思えます。 – jberryman
私に聞かせてください:どのくらいのスレッド(少なくとも大雑把な数)が構造にアクセスすると予想されますか?一度に何人いるの?変化のリストがどれだけ大きくなると思いますか? –
また、他の 'STM'操作で' update'を作成する必要がありますか、それとも常に独自のトランザクションで実行されますか? –