packages feed

agentx 0.1.0.4 → 0.1.0.5

raw patch · 8 files changed

+51/−50 lines, 8 filesPVP: major bump suggested

API removals or changes: PVP suggests a major version bump

API changes (from Hackage documentation)

- Network.Protocol.Snmp.AgentX.Types: evalMIBTree :: MIBTree IO a -> SubAgent a
- Network.Protocol.Snmp.AgentX.Types: mutex :: SubAgentState -> MVar ()
- Network.Protocol.Snmp.AgentX: Update :: (forall m. (Monad m, MonadIO m, Functor m) => m [MIB]) -> Update
+ Network.Protocol.Snmp.AgentX: Update :: IO [MIB] -> Update
- Network.Protocol.Snmp.AgentX: unUpdate :: Update -> forall m. (Monad m, MonadIO m, Functor m) => m [MIB]
+ Network.Protocol.Snmp.AgentX: unUpdate :: Update -> IO [MIB]
- Network.Protocol.Snmp.AgentX.MIBTree: Update :: (forall m. (Monad m, MonadIO m, Functor m) => m [MIB]) -> Update
+ Network.Protocol.Snmp.AgentX.MIBTree: Update :: IO [MIB] -> Update
- Network.Protocol.Snmp.AgentX.MIBTree: findMany :: (Monad m, MonadIO m, Functor m) => [OID] -> Maybe Context -> MIBTree m [MIB]
+ Network.Protocol.Snmp.AgentX.MIBTree: findMany :: [OID] -> Maybe Context -> MIBTree IO [MIB]
- Network.Protocol.Snmp.AgentX.MIBTree: findManyNext :: (Monad m, MonadIO m, Functor m) => [SearchRange] -> Maybe Context -> MIBTree m [MIB]
+ Network.Protocol.Snmp.AgentX.MIBTree: findManyNext :: [SearchRange] -> Maybe Context -> MIBTree IO [MIB]
- Network.Protocol.Snmp.AgentX.MIBTree: findNext :: (Monad m, MonadIO m, Functor m) => SearchRange -> Maybe Context -> MIBTree m MIB
+ Network.Protocol.Snmp.AgentX.MIBTree: findNext :: SearchRange -> Maybe Context -> MIBTree IO MIB
- Network.Protocol.Snmp.AgentX.MIBTree: findOne :: (Monad m, MonadIO m, Functor m) => OID -> Maybe Context -> MIBTree m MIB
+ Network.Protocol.Snmp.AgentX.MIBTree: findOne :: OID -> Maybe Context -> MIBTree IO MIB
- Network.Protocol.Snmp.AgentX.MIBTree: initModule :: (Monad m, MonadIO m, Functor m) => MIBTree m ()
+ Network.Protocol.Snmp.AgentX.MIBTree: initModule :: MIBTree IO ()
- Network.Protocol.Snmp.AgentX.MIBTree: mibToVarBind :: (Monad m, MonadIO m, Functor m) => MIB -> m VarBind
+ Network.Protocol.Snmp.AgentX.MIBTree: mibToVarBind :: MIB -> IO VarBind
- Network.Protocol.Snmp.AgentX.MIBTree: mkModule :: (Monad m, MonadIO m, Functor m) => OID -> [MIB] -> m Module
+ Network.Protocol.Snmp.AgentX.MIBTree: mkModule :: OID -> [MIB] -> IO Module
- Network.Protocol.Snmp.AgentX.MIBTree: unUpdate :: Update -> forall m. (Monad m, MonadIO m, Functor m) => m [MIB]
+ Network.Protocol.Snmp.AgentX.MIBTree: unUpdate :: Update -> IO [MIB]
- Network.Protocol.Snmp.AgentX.Types: SubAgentState :: IORef SysUptime -> IORef PacketID -> IORef Module -> MVar () -> Socket -> IORef (Maybe SessionID) -> IORef (Map TransactionID Transaction) -> SubAgentState
+ Network.Protocol.Snmp.AgentX.Types: SubAgentState :: IORef SysUptime -> IORef PacketID -> TVar Module -> Socket -> IORef (Maybe SessionID) -> IORef (Map TransactionID Transaction) -> SubAgentState
- Network.Protocol.Snmp.AgentX.Types: mibs :: SubAgentState -> IORef Module
+ Network.Protocol.Snmp.AgentX.Types: mibs :: SubAgentState -> TVar Module

Files

agentx.cabal view
@@ -2,7 +2,7 @@ -- documentation, see http://haskell.org/cabal/users-guide/  name:                agentx-version:             0.1.0.4+version:             0.1.0.5 synopsis:            AgentX protocol for write SNMP subagents description:         Native implementation agentx protocol (rfc2741)        license:             BSD3@@ -53,7 +53,7 @@                      , pipes                      , pipes-concurrency   hs-source-dirs:      src-  ghc-options: -Wall+  ghc-options: -Wall    default-language:    Haskell2010  executable agentx_example@@ -79,7 +79,7 @@                      , pipes                      , pipes-concurrency   hs-source-dirs:      src-  ghc-options: -Wall -O2 -threaded+  ghc-options: -Wall -O2 -threaded    default-language:    Haskell2010  
src/Main.hs view
@@ -48,7 +48,7 @@  dynTree :: IORef Value -> Update dynTree i = Update $ do-    Integer count <- liftIO $ readIORef i+    Integer count <- readIORef i     return $ concatMap fun [0 .. count]     where     fun x = [ mkObject (fromIntegral x) "trees" ("tree" ++ show x) Nothing
src/Network/Protocol/Snmp/AgentX/Handlers.hs view
@@ -88,10 +88,10 @@     liftIO . readIORef $ nowref  getHandler :: [OID] -> Maybe Context -> SubAgent [Either TaggedError VarBind]-getHandler xs mc = map Right <$> (liftIO . mapM mibToVarBind =<< evalMIBTree (findMany xs mc))+getHandler xs mc = map Right <$> (liftIO . mapM mibToVarBind =<< runMIBTree (findMany xs mc))  getNextHandler :: Maybe Context -> [SearchRange] -> SubAgent [Either TaggedError VarBind]-getNextHandler mc xs = map Right <$> (liftIO . mapM mibToVarBind =<< evalMIBTree (findManyNext xs mc))+getNextHandler mc xs = map Right <$> (liftIO . mapM mibToVarBind =<< runMIBTree (findManyNext xs mc))  getBulkHandler :: Maybe Context -> NonRepeaters -> MaxRepeaters -> [SearchRange] -> SubAgent [Either TaggedError VarBind] getBulkHandler = undefined
src/Network/Protocol/Snmp/AgentX/MIBTree/MIBTree.hs view
@@ -33,10 +33,10 @@ -- import Debug.Trace  -- | build tree and init module-initModule :: (Monad m, MonadIO m, Functor m) =>  MIBTree m ()+initModule :: MIBTree IO () initModule = flip forM_ evalTree =<< toUpdateList  <$> gets ou       where-    evalTree :: (Monad m, MonadIO m, Functor m) => MIB -> MIBTree m ()+    evalTree :: MIB -> MIBTree IO ()     evalTree obj = do         (mibs, updates) <- buildTree <$> (lift $ unUpdate . fromJust . update $ obj)         case updates of@@ -107,10 +107,10 @@         else ObjectType (L.get startOID s) (last $ L.get startOID s) "" "" Nothing (rsValue EndOfMibView)  -- | find one MIB -findOne :: (Monad m, MonadIO m, Functor m) => +findOne ::        OID  -- ^ path for find     -> Maybe Context -- ^ context, you can have many values with one path and different context-    -> MIBTree m MIB +    -> MIBTree IO MIB  findOne ys mcontext = do     -- init zippers     modify zipper top@@ -166,14 +166,14 @@   -- | like findOne, but for many paths-findMany :: (Monad m, MonadIO m, Functor m) => [OID] -> Maybe Context -> MIBTree m [MIB]+findMany :: [OID] -> Maybe Context -> MIBTree IO [MIB] findMany xs mc = mapM (flip findOne mc) xs  -- | find next node in MIBTree -findNext :: (Monad m, MonadIO m, Functor m) => +findNext ::        SearchRange  -- ^ SearchRange (getwalk or getnext requests)     -> Maybe Context -- ^ context-    -> MIBTree m MIB -- ^ search result+    -> MIBTree IO MIB -- ^ search result findNext sr mcontext = do     modify zipper top     modify ou top@@ -245,7 +245,7 @@ getFocus _ = error "getFocus"  -- | like findNext-findManyNext :: (Monad m, MonadIO m, Functor m) => [SearchRange] -> Maybe Context -> MIBTree m [MIB]+findManyNext :: [SearchRange] -> Maybe Context -> MIBTree IO [MIB] findManyNext xs mc = mapM (flip findNext mc) xs  
src/Network/Protocol/Snmp/AgentX/MIBTree/Tree.hs view
@@ -24,6 +24,7 @@  data Move b a = Next (b a)               | Level (b a)+              deriving Eq  instance (Show a, Show (b a)) => Show (Move b a) where     show (Next x) = "\nNext " ++ show x
src/Network/Protocol/Snmp/AgentX/MIBTree/Types.hs view
@@ -52,7 +52,7 @@             }  -- | Update, for rebuild oid tree in runtime-newtype Update = Update { unUpdate :: forall  m . (Monad m, MonadIO m, Functor m) =>  m [MIB] }+newtype Update = Update { unUpdate :: IO [MIB] }  type IValue = ContextedValue PVal   type IUpdate = ContextedValue Update @@ -109,6 +109,12 @@  mkLabel ''Module +instance Eq (ContextedValue a) where+    _ == _ = True++instance Eq Module where+    (Module z o _ _) == (Module z1 o1 _ _) = (z == z1) && (o == o1)+ instance Show Module where     show (Module z ou' _ _) = show z ++ "\n" ++ show ou' @@ -116,10 +122,10 @@ type MIBTree = StateT Module    -- | Constructor for Module-mkModule :: (Monad m, MonadIO m, Functor m) => +mkModule ::       OID -- ^ base module OID   -> [MIB] -- ^ all MIB for create module-  -> m Module +  -> IO Module  mkModule moduleOid mibs = do     reg <- liftIO $ newEmptyMVar     return $ Module (toZipper . fst . buildTree $ mibs) (toZipper . snd . buildTree $ mibs) moduleOid reg@@ -215,8 +221,8 @@ isWritable _ = False  -- | convert MIB to VarBind-mibToVarBind :: (Monad m, MonadIO m, Functor m) => MIB -> m VarBind+mibToVarBind :: MIB -> IO VarBind mibToVarBind m = do-    v <- liftIO $ readAIO (val m) +    v <- readAIO (val m)      return $ mkVarBind (oi m) v 
src/Network/Protocol/Snmp/AgentX/Service.hs view
@@ -12,7 +12,6 @@  import Network.Socket (close, Socket, socket, Family(AF_UNIX), SocketType(Stream), connect, SockAddr(SockAddrUnix)) import Network.Socket.ByteString.Lazy (recv, send)-import Control.Concurrent (killThread, threadDelay, ThreadId, myThreadId) import Data.Binary (encode, decode) import Data.Monoid ((<>)) import Control.Applicative hiding (empty)@@ -23,10 +22,11 @@ import Data.Fixed (div') import Data.Time.Clock.POSIX (getPOSIXTime) import System.IO (hSetBuffering, stdout, BufferMode(LineBuffering))-import Pipes.Concurrent (spawn, forkIO, fromInput, toOutput, unbounded)+import Pipes.Concurrent (spawn, fromInput, toOutput, unbounded) import Pipes import Pipes.Lift-import Control.Concurrent.MVar+import GHC.Conc hiding (yield)+import Control.Concurrent.MVar (takeMVar) import Data.Default import qualified Data.Map.Strict as Map  import qualified Data.Label as DL@@ -77,22 +77,20 @@     regPid <- fiber st $ resp >-> registrator >->  output     -- start server fibers     serverPid <-  fiber st $ req >-> server-    serverPid1 <-  fiber st $ req >-> server-    serverPid2 <-  fiber st $ req >-> server     -- start agent fiber     agentPid <- fiber st $ resp >-> runClient (maybe def id mclient) >-> output     regPidTimer <- registerTimer st     mainPid <- myThreadId     let stopAgent = do             liftIO $ putStrLn "unregister all MIB"-            evalStateT unregisterFullTree =<< readIORef (mibs st)+            evalStateT unregisterFullTree =<< readTVarIO (mibs st)             liftIO $ threadDelay 1000000-            void $ mapM (liftIO . killThread) [serverPid, serverPid1, serverPid2, sortPid, agentPid, regPid, timer, regPidTimer] +            void $ mapM (liftIO . killThread) [serverPid, sortPid, agentPid, regPid, timer, regPidTimer]              throwTo mainPid ExitSuccess     void $ installHandler keyboardSignal (Catch stopAgent) Nothing     void $ installHandler sigTERM (Catch stopAgent) Nothing     void $ installHandler sigQUIT (Catch stopAgent) Nothing-    void $ installHandler sigUSR1 (Catch (print =<< readIORef (mibs st))) Nothing+    void $ installHandler sigUSR1 (Catch (print =<< readTVarIO (mibs st))) Nothing     forever $ threadDelay 10000000  initAgent :: OID -> [MIB] -> Socket -> IO SubAgentState@@ -101,16 +99,15 @@     sessionsIORef <- newIORef Nothing     packetCounterIORef <- newIORef minBound     mod' <- mkModule modOid tree -    moduleIORef <- newIORef =<< flip execStateT mod' (initModule >> registerFullTree) -    m <- newMVar ()+    moduleIORef <- newTVarIO =<< flip execStateT mod' (initModule >> registerFullTree)      transactionsIORef <- newIORef Map.empty-    return $ SubAgentState sysUptimeIORef packetCounterIORef moduleIORef m socket' sessionsIORef transactionsIORef+    return $ SubAgentState sysUptimeIORef packetCounterIORef moduleIORef socket' sessionsIORef transactionsIORef  registerTimer :: SubAgentState -> IO ThreadId registerTimer st = forkIO . forever $ do-    oldTree <- evalStateT askTree =<< readIORef (mibs st)+    oldTree <- evalStateT askTree =<< readTVarIO (mibs st)     liftIO $ threadDelay 1000000-    evalStateT (flip regByDiff oldTree =<< askTree) =<< readIORef (mibs st)+    evalStateT (flip regByDiff oldTree =<< askTree) =<< readTVarIO (mibs st) --------------------------------------------------------------------------- -- Pipes eval  ---------------------------------------------------------------------------@@ -120,7 +117,6 @@ server :: Consumer Packet SubAgent () server = forever $ do     m <- await-    -- ask >>= flip fiber (yield m >-> server' >-> _dp "out" >-> output)     ask >>= flip fiber (yield m >-> server' >-> output)  fiber :: MonadIO m => SubAgentState -> Effect SubAgent () -> m ThreadId@@ -203,7 +199,7 @@ register :: SubAgent [Packet] register = do     s <- mibs <$> ask-    m  <- liftIO $ readIORef s+    m  <- liftIO $ readTVarIO s     (toReg, toUnReg) <- liftIO $ takeMVar (DL.get MIBTree.register m) --    liftIO $ mapM_ (\x -> print ("R " ++ show x)) toReg --    liftIO $ mapM_ (\x -> print ("UR " ++ show x)) toUnReg@@ -221,7 +217,7 @@ open :: SubAgent Packet open = do     s <- mibs <$> ask-    m <- liftIO $ readIORef s+    m <- liftIO $ readTVarIO s     let open' = Open minBound (DL.get moduleOID m) ("Haskell AgentX sub-aagent")     return $ mkPacket def open' def minBound minBound minBound  
src/Network/Protocol/Snmp/AgentX/Types.hs view
@@ -1,7 +1,6 @@ module Network.Protocol.Snmp.AgentX.Types  ( SubAgentState(..) , Transaction(..)-, evalMIBTree , runMIBTree , SubAgent , TransactionState(..)@@ -11,9 +10,9 @@ import Control.Monad.State.Strict import Control.Monad.Reader import Network.Socket hiding (recv)-import Control.Concurrent.MVar import Control.Applicative import Data.IORef+import GHC.Conc import Data.Map  import Network.Protocol.Snmp.AgentX.Packet @@ -35,8 +34,7 @@ data SubAgentState = SubAgentState   { sysuptime :: IORef SysUptime   , packetCounter :: IORef PacketID-  , mibs :: IORef Module -  , mutex :: MVar ()+  , mibs :: TVar Module    , sock :: Socket   , sessions :: IORef (Maybe SessionID)   , transactions :: IORef (Map TransactionID Transaction)@@ -45,18 +43,18 @@ type SubAgent = ReaderT SubAgentState IO  --- | run MIBTree in SubAgent context, with lock (access to Module read-write)+-- | run MIBTree in SubAgent context, without lock, if trees was changed, retry runMIBTree :: MIBTree IO a -> SubAgent a runMIBTree f = do     st <- mibs <$> ask-    m <- mutex <$> ask-    lift $ withMVar m $ \() -> do-        (a, newst) <- runStateT f =<< (liftIO $ readIORef st)-        atomicWriteIORef st newst-        return a+    oldst <- liftIO $ readTVarIO st+    (a, newst) <- liftIO $ runStateT f oldst+    result <- lift . atomically $ do+        oldst' <- readTVar st+        if oldst' == newst +           then writeTVar st newst >> return True+           else return False+    if result+       then return a+       else runMIBTree f --- | eval MIBTree in SubAgent context without lock (access to Module read only)-evalMIBTree :: MIBTree IO a -> SubAgent a-evalMIBTree f = do-    st <- mibs <$> ask-    liftIO $ evalStateT f =<< (liftIO $ readIORef st)