On Mon, Oct 14, 2013 at 10:25:31AM +0200, Hrvoje Ribicic wrote:
> The instance queries have a field called console which requires an
> extra RPC call. This commit allows extra parameters to be passed on
> to the query logic, which allows us to determine when to make the
> extra call.
> 
> Signed-off-by: Hrvoje Ribicic <[email protected]>
> ---
>  src/Ganeti/Query/Instance.hs | 21 ++++++++++++++-------
>  src/Ganeti/Query/Query.hs    | 31 ++++++++++++++++++++-----------
>  2 files changed, 34 insertions(+), 18 deletions(-)
> 
> diff --git a/src/Ganeti/Query/Instance.hs b/src/Ganeti/Query/Instance.hs
> index 6dc74f2..0651442 100644
> --- a/src/Ganeti/Query/Instance.hs
> +++ b/src/Ganeti/Query/Instance.hs
> @@ -819,20 +819,27 @@ getHypervisorSpecs cfg instances =
>    in zip hvs . map ((Map.!) hvParamMap . hypervisorToRaw) $ hvs
>  
>  -- | Collect live data from RPC query if enabled.
> -collectLiveData :: Bool -> ConfigData -> [Instance] -> IO [(Instance, 
> Runtime)]
> -collectLiveData False _ instances =
> +collectLiveData :: Bool        -- ^ Live queries allowed
> +                -> ConfigData  -- ^ The cluster config
> +                -> [String]    -- ^ The requested fields
> +                -> [Instance]  -- ^ The instance objects
> +                -> IO [(Instance, Runtime)]
> +collectLiveData False _ _ instances =
>    return $ zip instances
>             (repeat (Left $ RpcResultError "Live data disabled"))
> -collectLiveData True cfg instances = do
> +collectLiveData True cfg fields instances = do
>    let hvSpecs = getHypervisorSpecs cfg instances
>        instanceNodes = nub . justOk $
>                          map (getNode cfg . instPrimaryNode) instances
>        goodNodes = nodesWithValidConfig cfg instanceNodes
>    instInfoRes <- executeRpcCall goodNodes
>                     (RpcCallAllInstancesInfo hvSpecs)
> -  consInfoRes <- case getAllConsoleParams cfg instances of
> -    Bad _ -> return . zip goodNodes . repeat . Left $ RpcResultError
> -               "Cannot construct parameters for console info call"
> -    Ok  p -> executeRpcCalls $ consoleParamsToCalls p
> +  consInfoRes <-
> +    if "console" `elem` fields
> +      then case getAllConsoleParams cfg instances of
> +        Bad _ -> return . zip goodNodes . repeat . Left $ RpcResultError
> +                   "Cannot construct parameters for console info call"
> +        Ok  p -> executeRpcCalls $ consoleParamsToCalls p
> +      else return [] -- The information is not necessary
>    return . zip instances .
>             map (extractLiveInfo instInfoRes consInfoRes) $ instances
> diff --git a/src/Ganeti/Query/Query.hs b/src/Ganeti/Query/Query.hs
> index 2752fd4..758aee1 100644
> --- a/src/Ganeti/Query/Query.hs
> +++ b/src/Ganeti/Query/Query.hs
> @@ -80,6 +80,12 @@ import Ganeti.Path
>  import Ganeti.Types
>  import Ganeti.Utils
>  
> +

Extra empty line.

> +-- | Collector type
> +data CollectorType a b =
> +  CollectorSimple     (Bool -> ConfigData -> [a] -> IO [(a, b)]) |
> +  CollectorFieldAware (Bool -> ConfigData -> [String] -> [a] -> IO [(a, b)])

Just to share my personal preference, I like to tie the constructor
names to the type name.  I especially like the way Template Haskell
does it, for example,

  data Exp
    = ConE
    | LitE
    | VarE
    | ...

Anyway, leave the choice of names up to you.  In any case,
indentation:

  data ...
    = ...
    | ...

> +
>  -- * Helper functions
>  
>  -- | Builds an unknown field definition.
> @@ -155,7 +161,7 @@ getRequestedJobIDs qfilter =
>  -- | Generic query implementation for resources that are backed by
>  -- some configuration objects.
>  genericQuery :: FieldMap a b       -- ^ Field map
> -             -> (Bool -> ConfigData -> [a] -> IO [(a, b)]) -- ^ Collector
> +             -> CollectorType a b  -- ^ Collector

Saying that the 'FieldMap' is the 'Field map' and the 'CollectorType'
is the 'Collector' isn't very helpful.

>               -> (a -> String)      -- ^ Object to name function
>               -> (ConfigData -> Container a) -- ^ Get all objects from config
>               -> (ConfigData -> String -> ErrorResult a) -- ^ Lookup object
> @@ -181,7 +187,9 @@ genericQuery fieldsMap collector nameFn configFn getFn cfg
>    fobjects <- resultT $ filterM (\n -> evaluateFilter cfg Nothing n cfilter)
>                          objects
>    -- here run the runtime data gathering...

This comment is weird.  Why not just 'Run the runtime data gathering' ?

> -  runtimes <- lift $ collector live' cfg fobjects
> +  runtimes <- case collector of
> +    CollectorSimple     collFn -> lift $ collFn live' cfg fobjects
> +    CollectorFieldAware collFn -> lift $ collFn live' cfg fields fobjects
>    -- ... then filter again the results, based on gathered runtime data

Weird comment again. 'Filter again the results, ...'

Thanks,
Jose

>    let fdata = map (\(obj, runtime) ->
>                       map (execGetter cfg runtime obj) fgetters)
> @@ -205,25 +213,26 @@ queryInner :: ConfigData   -- ^ The current 
> configuration
>             -> IO (ErrorResult QueryResult) -- ^ Result
>  
>  queryInner cfg live (Query (ItemTypeOpCode QRNode) fields qfilter) wanted =
> -  genericQuery Node.fieldsMap Node.collectLiveData nodeName configNodes 
> getNode
> -               cfg live fields qfilter wanted
> +  genericQuery Node.fieldsMap (CollectorSimple Node.collectLiveData) nodeName
> +               configNodes getNode cfg live fields qfilter wanted
>  
>  queryInner cfg live (Query (ItemTypeOpCode QRInstance) fields qfilter) 
> wanted =
> -  genericQuery Instance.fieldsMap Instance.collectLiveData instName
> -               configInstances getInstance cfg live fields qfilter wanted
> +  genericQuery Instance.fieldsMap (CollectorFieldAware 
> Instance.collectLiveData)
> +               instName configInstances getInstance cfg live fields qfilter
> +               wanted
>  
>  queryInner cfg live (Query (ItemTypeOpCode QRGroup) fields qfilter) wanted =
> -  genericQuery Group.fieldsMap Group.collectLiveData groupName 
> configNodegroups
> -               getGroup cfg live fields qfilter wanted
> +  genericQuery Group.fieldsMap (CollectorSimple Group.collectLiveData) 
> groupName
> +               configNodegroups getGroup cfg live fields qfilter wanted
>  
>  queryInner cfg live (Query (ItemTypeOpCode QRNetwork) fields qfilter) wanted 
> =
> -  genericQuery Network.fieldsMap Network.collectLiveData
> +  genericQuery Network.fieldsMap (CollectorSimple Network.collectLiveData)
>                 (fromNonEmpty . networkName)
>                 configNetworks getNetwork cfg live fields qfilter wanted
>  
>  queryInner cfg live (Query (ItemTypeOpCode QRExport) fields qfilter) wanted =
> -  genericQuery Export.fieldsMap Export.collectLiveData nodeName configNodes
> -               getNode cfg live fields qfilter wanted
> +  genericQuery Export.fieldsMap (CollectorSimple Export.collectLiveData)
> +               nodeName configNodes getNode cfg live fields qfilter wanted
>  
>  queryInner _ _ (Query qkind _ _) _ =
>    return . Bad . GenericError $ "Query '" ++ show qkind ++ "' not supported"
> -- 
> 1.8.4
> 

-- 
Jose Antonio Lopes
Ganeti Engineering
Google Germany GmbH
Dienerstr. 12, 80331, München

Registergericht und -nummer: Hamburg, HRB 86891
Sitz der Gesellschaft: Hamburg
Geschäftsführer: Graham Law, Christine Elizabeth Flores
Steuernummer: 48/725/00206
Umsatzsteueridentifikationsnummer: DE813741370

Reply via email to