ngx-export-tools-0.1.1.0: Extra tools for Nginx haskell module

Copyright(c) Alexey Radkov 2018
LicenseBSD-style
Maintaineralexey.radkov@gmail.com
Stabilityexperimental
Portabilitynon-portable (requires Template Haskell)
Safe HaskellNone
LanguageHaskell98

NgxExport.Tools

Contents

Description

Extra tools for using in custom Haskell code with nginx-haskell-module.

Synopsis

Various useful functions and data

exitWorkerProcess :: IO () Source #

Terminates current Nginx worker process.

Nginx master process shall spawn a new worker process thereafter.

terminateWorkerProcess :: IO () Source #

Terminates current Nginx worker process.

Nginx master process shall not spawn a new worker process thereafter.

ngxNow :: IO CTime Source #

Returns current time as the number of seconds elapsed since UNIX epoch.

The value is taken from Nginx core, so no additional system calls get involved. On the other hand, it means that this is only safe to use from an Nginx worker's main thread, i.e. in synchronous Haskell handlers and service hooks. Be also aware that this is a small type casting hack: the value is interpreted as being of type time_t while having been actually wrapped in a bigger C struct as its first element.

threadDelaySec :: Int -> IO () Source #

Delays current thread for the specified number of seconds.

data TimeInterval Source #

Time intervals.

Constructors

Hr Int

Hours

Min Int

Minutes

Sec Int

Seconds

HrMin Int Int

Hours and minutes

MinSec Int Int

Minutes and seconds

Instances
Read TimeInterval Source # 
Instance details

Defined in NgxExport.Tools

Generic TimeInterval Source # 
Instance details

Defined in NgxExport.Tools

Associated Types

type Rep TimeInterval :: Type -> Type #

Lift TimeInterval Source # 
Instance details

Defined in NgxExport.Tools

Methods

lift :: TimeInterval -> Q Exp #

FromJSON TimeInterval Source # 
Instance details

Defined in NgxExport.Tools

type Rep TimeInterval Source # 
Instance details

Defined in NgxExport.Tools

toSec :: TimeInterval -> Int Source #

Converts a time interval into seconds.

Exporters of simple services

There are a number of exporters for simple services. Here simplicity means avoiding boilerplate code regarding to efficient reading of typed configurations and timed restarts of services. All simple services have type

ByteString -> Bool -> IO ByteString

which corresponds to the type of usual services from module NgxExport.

Below is a toy example.

File test_tools.hs.

{-# LANGUAGE TemplateHaskell, DeriveGeneric #-}

module TestTools where

import           NgxExport.Tools

import           Data.ByteString (ByteString)
import qualified Data.ByteString.Lazy as L
import qualified Data.ByteString.Lazy.Char8 as C8L
import           Data.Aeson
import           GHC.Generics

test :: ByteString -> Bool -> IO L.ByteString
test = const . return . L.fromStrict
ngxExportSimpleService 'test $
    PersistentService $ Just $ Sec 10

newtype ConfRead = ConfRead Int deriving (Read, Show)

testRead :: ConfRead -> Bool -> IO L.ByteString
testRead c = const $ return $ C8L.pack $ show c
ngxExportSimpleServiceTyped 'testRead ''ConfRead $
    PersistentService $ Just $ Sec 10

data ConfReadJSON = ConfReadJSONCon1 Int
                  | ConfReadJSONCon2 deriving (Generic, Show)
instance FromJSON ConfReadJSON

testReadJSON :: ConfReadJSON -> Bool -> IO L.ByteString
testReadJSON c = const $ return $ C8L.pack $ show c
ngxExportSimpleServiceTypedAsJSON 'testReadJSON ''ConfReadJSON
    SingleShotService

Here three simple services of various types are defined: test, testRead, and testReadJSON. As soon as they merely echo their arguments into their service variables, they must sleep for a while between iterations. Sleeps are managed by strategies defined in type ServiceMode. There are basically three sleeping strategies:

In this toy example the most efficient sleeping strategy is a single-shot service because data is not altered during runtime. Under the hood, the single-shot strategy is implemented as periodical sleeps (with period of Hr 1), except it runs the handler only on the first iteration, while afterwards it merely returns empty values: as such, this strategy should be accompanied by Nginx directive haskell_service_var_ignore_empty.

All three services ignore their second parameter (of type Bool) denoting the first run of the service.

File nginx.conf.

user                    nobody;
worker_processes        2;

events {
    worker_connections  1024;
}

http {
    default_type        application/octet-stream;
    sendfile            on;

    haskell load /var/lib/nginx/test_tools.so;

    haskell_run_service simpleService_test $hs_test
            test;

    haskell_run_service simpleService_testRead $hs_testRead
            'ConfRead 20';

    haskell_run_service simpleService_testReadJSON $hs_testReadJSON
            '{"tag":"ConfReadJSONCon1", "contents":56}';

    haskell_service_var_ignore_empty $hs_testReadJSON;

    server {
        listen       8010;
        server_name  main;
        error_log    /tmp/nginx-test-haskell-error.log;
        access_log   /tmp/nginx-test-haskell-access.log;

        location / {
            echo "Service variables:";
            echo "  hs_test: $hs_test";
            echo "  hs_testRead: $hs_testRead";
            echo "  hs_testReadJSON: $hs_testReadJSON";
        }
    }
}

Notice that Haskel handlers defined in test_tools.hs are referred from the Nginx configuration file with prefix simpleService_.

Let's run a simple test.

$ curl 'http://localhost:8010/'
Service variables:
  hs_test: test
  hs_testRead: ConfRead 20
  hs_testReadJSON: ConfReadJSONCon1 56

data ServiceMode Source #

Defines a sleeping strategy.

Single-shot services should be accompanied by Nginx directive haskell_service_var_ignore_empty.

Constructors

PersistentService (Maybe TimeInterval)

Persistent service (with or without periodical sleeps)

SingleShotService

Single-shot service

ngxExportSimpleService Source #

Arguments

:: Name

Name of the service

-> ServiceMode

Service mode

-> Q [Dec] 

Exports a simple service with specified name and service mode.

The service expects a plain ByteString as its first argument.

ngxExportSimpleServiceTyped Source #

Arguments

:: Name

Name of the service

-> Name

Name of the custom type

-> ServiceMode

Service mode

-> Q [Dec] 

Exports a simple service with specified name and service mode.

The service expects a custom type deriving Read as its first argument. For the sake of efficiency, the object of this custom type gets deserialized into a global IORef data storage on the first service run to be further accessed directly from the storage.

ngxExportSimpleServiceTypedAsJSON Source #

Arguments

:: Name

Name of the service

-> Name

Name of the custom type

-> ServiceMode

Service mode

-> Q [Dec] 

Exports a simple service with specified name and service mode.

The service expects a custom type deriving FromJSON as its first argument. For the sake of efficiency, the object of this custom type gets deserialized into a global IORef data storage on the first service run to be further accessed directly from the storage.

Re-exported data constructors from Foreign.C

newtype CInt #

Haskell type representing the C int type.

Constructors

CInt Int32 
Instances
Bounded CInt 
Instance details

Defined in Foreign.C.Types

Enum CInt 
Instance details

Defined in Foreign.C.Types

Methods

succ :: CInt -> CInt #

pred :: CInt -> CInt #

toEnum :: Int -> CInt #

fromEnum :: CInt -> Int #

enumFrom :: CInt -> [CInt] #

enumFromThen :: CInt -> CInt -> [CInt] #

enumFromTo :: CInt -> CInt -> [CInt] #

enumFromThenTo :: CInt -> CInt -> CInt -> [CInt] #

Eq CInt 
Instance details

Defined in Foreign.C.Types

Methods

(==) :: CInt -> CInt -> Bool #

(/=) :: CInt -> CInt -> Bool #

Integral CInt 
Instance details

Defined in Foreign.C.Types

Methods

quot :: CInt -> CInt -> CInt #

rem :: CInt -> CInt -> CInt #

div :: CInt -> CInt -> CInt #

mod :: CInt -> CInt -> CInt #

quotRem :: CInt -> CInt -> (CInt, CInt) #

divMod :: CInt -> CInt -> (CInt, CInt) #

toInteger :: CInt -> Integer #

Num CInt 
Instance details

Defined in Foreign.C.Types

Methods

(+) :: CInt -> CInt -> CInt #

(-) :: CInt -> CInt -> CInt #

(*) :: CInt -> CInt -> CInt #

negate :: CInt -> CInt #

abs :: CInt -> CInt #

signum :: CInt -> CInt #

fromInteger :: Integer -> CInt #

Ord CInt 
Instance details

Defined in Foreign.C.Types

Methods

compare :: CInt -> CInt -> Ordering #

(<) :: CInt -> CInt -> Bool #

(<=) :: CInt -> CInt -> Bool #

(>) :: CInt -> CInt -> Bool #

(>=) :: CInt -> CInt -> Bool #

max :: CInt -> CInt -> CInt #

min :: CInt -> CInt -> CInt #

Read CInt 
Instance details

Defined in Foreign.C.Types

Real CInt 
Instance details

Defined in Foreign.C.Types

Methods

toRational :: CInt -> Rational #

Show CInt 
Instance details

Defined in Foreign.C.Types

Methods

showsPrec :: Int -> CInt -> ShowS #

show :: CInt -> String #

showList :: [CInt] -> ShowS #

Storable CInt 
Instance details

Defined in Foreign.C.Types

Methods

sizeOf :: CInt -> Int #

alignment :: CInt -> Int #

peekElemOff :: Ptr CInt -> Int -> IO CInt #

pokeElemOff :: Ptr CInt -> Int -> CInt -> IO () #

peekByteOff :: Ptr b -> Int -> IO CInt #

pokeByteOff :: Ptr b -> Int -> CInt -> IO () #

peek :: Ptr CInt -> IO CInt #

poke :: Ptr CInt -> CInt -> IO () #

Bits CInt 
Instance details

Defined in Foreign.C.Types

FiniteBits CInt 
Instance details

Defined in Foreign.C.Types

newtype CUInt #

Haskell type representing the C unsigned int type.

Constructors

CUInt Word32 
Instances
Bounded CUInt 
Instance details

Defined in Foreign.C.Types

Enum CUInt 
Instance details

Defined in Foreign.C.Types

Eq CUInt 
Instance details

Defined in Foreign.C.Types

Methods

(==) :: CUInt -> CUInt -> Bool #

(/=) :: CUInt -> CUInt -> Bool #

Integral CUInt 
Instance details

Defined in Foreign.C.Types

Num CUInt 
Instance details

Defined in Foreign.C.Types

Ord CUInt 
Instance details

Defined in Foreign.C.Types

Methods

compare :: CUInt -> CUInt -> Ordering #

(<) :: CUInt -> CUInt -> Bool #

(<=) :: CUInt -> CUInt -> Bool #

(>) :: CUInt -> CUInt -> Bool #

(>=) :: CUInt -> CUInt -> Bool #

max :: CUInt -> CUInt -> CUInt #

min :: CUInt -> CUInt -> CUInt #

Read CUInt 
Instance details

Defined in Foreign.C.Types

Real CUInt 
Instance details

Defined in Foreign.C.Types

Methods

toRational :: CUInt -> Rational #

Show CUInt 
Instance details

Defined in Foreign.C.Types

Methods

showsPrec :: Int -> CUInt -> ShowS #

show :: CUInt -> String #

showList :: [CUInt] -> ShowS #

Storable CUInt 
Instance details

Defined in Foreign.C.Types

Methods

sizeOf :: CUInt -> Int #

alignment :: CUInt -> Int #

peekElemOff :: Ptr CUInt -> Int -> IO CUInt #

pokeElemOff :: Ptr CUInt -> Int -> CUInt -> IO () #

peekByteOff :: Ptr b -> Int -> IO CUInt #

pokeByteOff :: Ptr b -> Int -> CUInt -> IO () #

peek :: Ptr CUInt -> IO CUInt #

poke :: Ptr CUInt -> CUInt -> IO () #

Bits CUInt 
Instance details

Defined in Foreign.C.Types

FiniteBits CUInt 
Instance details

Defined in Foreign.C.Types