-
Notifications
You must be signed in to change notification settings - Fork 29
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Resource limit #55
base: master
Are you sure you want to change the base?
Resource limit #55
Changes from all commits
240cea6
1ff4676
3e2186e
baeff32
05bd9cc
ac25d5b
cec5558
265d06d
ee7d216
8595a3c
1a1c56b
7c727b0
0b6738f
bb06cdf
984da57
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,3 +2,5 @@ stack.yaml.lock | |
test.log | ||
TAGS | ||
.stack-work/ | ||
dist-* | ||
cabal.project.local* |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
{-# LANGUAGE DeriveAnyClass #-} | ||
{-# LANGUAGE DeriveGeneric #-} | ||
{-# LANGUAGE OverloadedStrings #-} | ||
|
||
-- | Provides tools to facilitate database interactions during interactive | ||
-- development. | ||
module DevelDb where | ||
|
||
import Control.Exception (bracket) | ||
import Data.Aeson(FromJSON, ToJSON) | ||
import Data.ByteString.Char8 (ByteString, pack) | ||
import Data.Text (Text) | ||
import qualified Database.PostgreSQL.Simple as PGS | ||
import System.Environment (lookupEnv) | ||
|
||
import GHC.Generics | ||
|
||
import OddJobs.Migrations | ||
import OddJobs.Job | ||
import OddJobs.Types | ||
|
||
data TestJob = TestJob Text | ||
deriving (Eq, Show, Generic, FromJSON, ToJSON) | ||
|
||
devTableNames :: TableNames | ||
devTableNames = TableNames | ||
{ tnJob = "job", tnResource = "resource" } | ||
|
||
devConnectionString :: IO ByteString | ||
devConnectionString = do | ||
maybe (error "devConnectionString: Expected environment variable \"ODD_JOBS_DEV_DB_CONNECT\" to provide a connection string") | ||
pack | ||
<$> lookupEnv "ODD_JOBS_DEV_DB_CONNECT" | ||
|
||
createDevDatabase :: IO () | ||
createDevDatabase = do | ||
connStr <- devConnectionString | ||
conn <- PGS.connectPostgreSQL connStr | ||
PGS.withTransaction conn $ createJobTables conn devTableNames | ||
|
||
openDevConnection :: IO PGS.Connection | ||
openDevConnection = devConnectionString >>= PGS.connectPostgreSQL | ||
|
||
withDevConnection :: (PGS.Connection -> IO a) -> IO a | ||
withDevConnection = bracket openDevConnection PGS.close | ||
|
||
withDevTransaction :: (PGS.Connection -> IO a) -> IO a | ||
withDevTransaction act = | ||
withDevConnection $ \conn -> PGS.withTransaction conn (act conn) |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -34,7 +34,7 @@ import qualified System.Log.FastLogger as FLogger | |
mkConfig :: (LogLevel -> LogEvent -> IO ()) | ||
-- ^ "Structured logging" function. Ref: 'cfgLogger' | ||
-> TableName | ||
-- ^ DB table which holds your jobs. Ref: 'cfgTableName' | ||
-- ^ DB table which holds your jobs (resource table name will be generated). Ref: 'cfgTableNames' | ||
-> Pool Connection | ||
-- ^ DB connection-pool to be used by job-runner. Ref: 'cfgDbPool' | ||
-> ConcurrencyControl | ||
|
@@ -53,7 +53,39 @@ mkConfig :: (LogLevel -> LogEvent -> IO ()) | |
-- function, unless you know what you're doing. | ||
-> Config | ||
-- ^ The final 'Config' that can be used to start various job-runners | ||
mkConfig logger tname dbpool ccControl jrunner configOverridesFn = | ||
mkConfig logger tname = | ||
mkResourceConfig logger (simpleTableNames tname) | ||
|
||
-- | This function gives you a 'Config' with a bunch of sensible defaults | ||
-- already applied, but it allows the specification of all database table | ||
-- names.. It requires the bare minimum of other configuration parameters that | ||
-- this library cannot assume on your behalf. | ||
-- | ||
-- It makes a few __important assumptions__ about your 'jobPayload 'JSON, which | ||
-- are documented in 'defaultJobType'. | ||
mkResourceConfig :: (LogLevel -> LogEvent -> IO ()) | ||
-- ^ "Structured logging" function. Ref: 'cfgLogger' | ||
-> TableNames | ||
-- ^ DB tables which hold your jobs and resources | ||
-> Pool Connection | ||
-- ^ DB connection-pool to be used by job-runner. Ref: 'cfgDbPool' | ||
-> ConcurrencyControl | ||
-- ^ Concurrency configuration. Ref: 'cfgConcurrencyControl' | ||
-> (Job -> IO ()) | ||
-- ^ The actual "job runner" which contains your application code. Ref: 'cfgJobRunner' | ||
-> (Config -> Config) | ||
-- ^ A function that allows you to modify the \"interim config\". The | ||
-- \"interim config\" will cotain a bunch of in-built default config | ||
-- params, along with the config params that you\'ve just provided | ||
-- (i.e. logging function, table name, DB pool, etc). You can use this | ||
-- function to override values in the \"interim config\". If you do not | ||
-- wish to modify the \"interim config\" just pass 'Prelude.id' as an | ||
-- argument to this parameter. __Note:__ it is strongly recommended | ||
-- that you __do not__ modify the generated 'Config' outside of this | ||
-- function, unless you know what you're doing. | ||
-> Config | ||
-- ^ The final 'Config' that can be used to start various job-runners | ||
mkResourceConfig logger tnames dbpool ccControl jrunner configOverridesFn = | ||
let cfg = configOverridesFn $ Config | ||
{ cfgPollingInterval = defaultPollingInterval | ||
, cfgOnJobSuccess = (const $ pure ()) | ||
|
@@ -63,20 +95,20 @@ mkConfig logger tname dbpool ccControl jrunner configOverridesFn = | |
, cfgDbPool = dbpool | ||
, cfgOnJobStart = (const $ pure ()) | ||
, cfgDefaultMaxAttempts = 10 | ||
, cfgTableName = tname | ||
, cfgTableNames = tnames | ||
, cfgOnJobTimeout = (const $ pure ()) | ||
, cfgConcurrencyControl = ccControl | ||
, cfgDefaultResourceLimit = 1 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. My thought is that |
||
, cfgPidFile = Nothing | ||
, cfgJobType = defaultJobType | ||
, cfgDefaultJobTimeout = Seconds 600 | ||
, cfgJobToHtml = defaultJobToHtml (cfgJobType cfg) | ||
, cfgAllJobTypes = (defaultDynamicJobTypes (cfgTableName cfg) (cfgJobTypeSql cfg)) | ||
, cfgAllJobTypes = (defaultDynamicJobTypes (cfgTableNames cfg) (cfgJobTypeSql cfg)) | ||
, cfgJobTypeSql = defaultJobTypeSql | ||
} | ||
in cfg | ||
|
||
|
||
|
||
-- | If you aren't interested in structured logging, you can use this function | ||
-- to emit plain-text logs (or define your own). | ||
defaultLogStr :: (Job -> Text) | ||
|
@@ -184,11 +216,12 @@ defaultConstantJobTypes :: forall a . (Generic a, ConNames (Rep a)) | |
defaultConstantJobTypes _ = | ||
AJTFixed $ DL.map toS $ conNames (undefined :: a) | ||
|
||
defaultDynamicJobTypes :: TableName | ||
defaultDynamicJobTypes :: TableNames | ||
-> PGS.Query | ||
-> AllJobTypes | ||
defaultDynamicJobTypes tname jobTypeSql = AJTSql $ \conn -> do | ||
fmap (DL.map ((fromMaybe "(unknown)") . fromOnly)) $ PGS.query_ conn $ "select distinct(" <> jobTypeSql <> ") from " <> tname <> " order by 1 nulls last" | ||
defaultDynamicJobTypes tnames jobTypeSql = AJTSql $ \conn -> do | ||
fmap (DL.map ((fromMaybe "(unknown)") . fromOnly)) $ PGS.query_ conn $ | ||
"select distinct(" <> jobTypeSql <> ") from " <> tnJob tnames <> " order by 1 nulls last" | ||
|
||
-- | This makes __two important assumptions__. First, this /assumes/ that jobs | ||
-- in your app are represented by a sum-type. For example: | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This stuff was helpful for me during testing so I thought I'd leave it here.