Revision 9c45196b

b/src/Ganeti/Locking/Locks.hs
35 35
  , lockLevel
36 36
  ) where
37 37

  
38
import Control.Monad ((>=>), liftM)
38
import Control.Monad ((>=>))
39 39
import Control.Monad.Base (MonadBase, liftBase)
40 40
import Control.Monad.Error (MonadError, catchError)
41 41
import Data.List (stripPrefix)
......
44 44

  
45 45
import Ganeti.BasicTypes
46 46
import Ganeti.Errors (ResultG, GanetiException)
47
import Ganeti.JSON (readEitherString, fromJResultE, MaybeForJSON(..))
47
import Ganeti.JSON (readEitherString, fromJResultE)
48 48
import Ganeti.Locking.Allocation
49 49
import Ganeti.Locking.Types
50 50
import Ganeti.Logging.Lifted (MonadLog, logDebug, logEmergency)
......
189 189
-- identifier file.
190 190
--
191 191
-- The JobId isn't enough to identify a client as the master daemon
192
-- also handles RPC calls that aren't jobs, but which use the configuration.
193
-- Therefore it's needed to include the identification for threads.
194
-- An alternative would be to use something like @Either JobId RpcCallId@.
195
--
196
-- FIXME: Python threads are only unique wrt running threads, so it's possible
197
-- that a new thread will get a thread id that has been used before by another
198
-- finished thread. Since we rely on threads releasing their locks anyway,
199
-- this isn't a big issue, but in the future it'd be better to have a unique
200
-- identifier for each operation.
192
-- also handles client calls that aren't jobs, but which use the configuration.
193
-- These taks are identified by a unique name, reported to WConfD as a string.
201 194
data ClientId = ClientId
202
  { ciJobId :: Maybe JobId
203
  , ciThreadId :: Integer
195
  { ciIdentifier :: Either String JobId
204 196
  , ciLockFile :: FilePath
205 197
  }
206 198
  deriving (Ord, Eq, Show)
207 199

  
200
-- | Obtain the ClientID from its JSON representation.
201
clientIdFromJSON :: J.JSValue -> J.Result ClientId
202
clientIdFromJSON (J.JSArray [J.JSString s, J.JSString lf]) =
203
  J.Ok . ClientId (Left $ J.fromJSString s) $ J.fromJSString lf
204
clientIdFromJSON (J.JSArray [jsjid, J.JSString lf]) =
205
  J.readJSON jsjid >>= \jid -> J.Ok (ClientId (Right jid) (J.fromJSString lf))
206
clientIdFromJSON x = J.Error $ "malformed client id: " ++ show x
207

  
208 208
instance J.JSON ClientId where
209
  showJSON (ClientId jid tid lf) = J.showJSON (MaybeForJSON jid, tid, lf)
210
  readJSON = liftM (\(MaybeForJSON jid, tid, lf) -> ClientId jid tid lf)
211
             . J.readJSON
209
  showJSON (ClientId (Left name) lf) = J.showJSON (name, lf)
210
  showJSON (ClientId (Right jid) lf) = J.showJSON (jid, lf)
211
  readJSON = clientIdFromJSON
212 212

  
213 213
-- | The type of lock Allocations in Ganeti. In Ganeti, the owner of
214 214
-- locks are jobs.
b/test/hs/Test/Ganeti/Locking/Locks.hs
91 91
  readJSON (showJSON a) ==? Ok a
92 92

  
93 93
instance Arbitrary ClientId where
94
  arbitrary = ClientId <$> arbitrary <*> arbitrary <*> arbitrary
94
  arbitrary = ClientId <$> arbitrary <*> arbitrary
95 95

  
96 96
-- | Verify that readJSON . showJSON = Ok for ClientId
97 97
prop_ReadShow_ClientId :: Property

Also available in: Unified diff