Repository: twitter/scoot (language: python)

Issue:
eliminate scheduler's use of ice, make ci works
summary of change:
- update scheduler's main.go to create the necessary objects directly when starting the server
- eliminated scheduler's use of the config.go generated by bindata: moved the json configurations into variable defnitions (see scheduler/config/config.go)
- removed scheduler ice files.


Discussion / hints:
# [Codecov](https://codecov.io/gh/twitter/scoot/pull/536?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=twitter) Report
> Merging [#536](https://codecov.io/gh/twitter/scoot/pull/536?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=twitter) (737d86d) into [master](https://codecov.io/gh/twitter/scoot/commit/7f08cc3d4f97a723bf50920f31156fb146d13e64?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=twitter) (7f08cc3) will **decrease** coverage by `2.39%`.
> The diff coverage is `54.79%`.

> :exclamation: Current head 737d86d differs from pull request most recent head 91dc98f. Consider uploading reports for the commit 91dc98f to get more accurate results
[![Impacted file tree graph](https://codecov.io/gh/twitter/scoot/pull/536/graphs/tree.svg?width=650&height=150&src=pr&token=5WsicqfYFn&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=twitter)](https://codecov.io/gh/twitter/scoot/pull/536?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=twitter)

```diff
@@            Coverage Diff             @@
##           master     #536      +/-   ##
==========================================
- Coverage   54.30%   51.91%   -2.40%     
==========================================
  Files         120      119       -1     
  Lines        8638     8587      -51     
==========================================
- Hits         4691     4458     -233     
- Misses       3442     3611     +169     
- Partials      505      518      +13     
```


| [Impacted Files](https://codecov.io/gh/twitter/scoot/pull/536?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=twitter) | Coverage Δ | |
|---|---|---|
| [scheduler/scheduler/config/config.go](https://codecov.io/gh/twitter/scoot/pull/536/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=twitter#diff-c2NoZWR1bGVyL3NjaGVkdWxlci9jb25maWcvY29uZmlnLmdv) | `43.54% <45.00%> (ø)` | |
| [scheduler/server/cluster\_state.go](https://codecov.io/gh/twitter/scoot/pull/536/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=twitter#diff-c2NoZWR1bGVyL3NlcnZlci9jbHVzdGVyX3N0YXRlLmdv) | `85.40% <100.00%> (+0.32%)` | :arrow_up: |
| [scheduler/server/stateful\_scheduler.go](https://codecov.io/gh/twitter/scoot/pull/536/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=twitter#diff-c2NoZWR1bGVyL3NlcnZlci9zdGF0ZWZ1bF9zY2hlZHVsZXIuZ28=) | `62.96% <100.00%> (+0.38%)` | :arrow_up: |
| [saga/saga\_generators.go](https://codecov.io/gh/twitter/scoot/pull/536/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=twitter#diff-c2FnYS9zYWdhX2dlbmVyYXRvcnMuZ28=) | `0.00% <0.00%> (-82.98%)` | :arrow_down: |
| [scheduler/domain/generators.go](https://codecov.io/gh/twitter/scoot/pull/536/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=twitter#diff-c2NoZWR1bGVyL2RvbWFpbi9nZW5lcmF0b3JzLmdv) | `0.00% <0.00%> (-67.17%)` | :arrow_down: |
| [snapshot/bazel/bz\_tree.go](https://codecov.io/gh/twitter/scoot/pull/536/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=twitter#diff-c25hcHNob3QvYmF6ZWwvYnpfdHJlZS5nbw==) | `11.11% <0.00%> (-58.89%)` | :arrow_down: |
| [saga/saga\_state.go](https://codecov.io/gh/twitter/scoot/pull/536/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=twitter#diff-c2FnYS9zYWdhX3N0YXRlLmdv) | `48.64% <0.00%> (-39.46%)` | :arrow_down: |
| [scheduler/api/thrift/get\_status.go](https://codecov.io/gh/twitter/scoot/pull/536/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=twitter#diff-c2NoZWR1bGVyL2FwaS90aHJpZnQvZ2V0X3N0YXR1cy5nbw==) | `73.91% <0.00%> (-20.29%)` | :arrow_down: |
| [scheduler/server/task\_scheduler.go](https://codecov.io/gh/twitter/scoot/pull/536/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=twitter#diff-c2NoZWR1bGVyL3NlcnZlci90YXNrX3NjaGVkdWxlci5nbw==) | `64.28% <0.00%> (-5.96%)` | :arrow_down: |
| [scheduler/api/thrift/run\_job.go](https://codecov.io/gh/twitter/scoot/pull/536/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=twitter#diff-c2NoZWR1bGVyL2FwaS90aHJpZnQvcnVuX2pvYi5nbw==) | `40.47% <0.00%> (-4.77%)` | :arrow_down: |
| ... and [2 more](https://codecov.io/gh/twitter/scoot/pull/536/diff?src=pr&el=tree-more&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=twitter) | |

------

[Continue to review full report at Codecov](https://codecov.io/gh/twitter/scoot/pull/536?src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=twitter).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=twitter)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/twitter/scoot/pull/536?src=pr&el=footer&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=twitter). Last update [7f08cc3...91dc98f](https://codecov.io/gh/twitter/scoot/pull/536?src=pr&el=lastupdated&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=twitter). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=twitter).


Fix patch:
diff --git a/common/constants.go b/common/constants.go
new file mode 100644
index 000000000..0aac7f41e
--- /dev/null
+++ b/common/constants.go
@@ -0,0 +1,7 @@
+package common
+
+import (
+	"time"
+)
+
+const DefaultClientTimeout = time.Minute
diff --git a/common/endpoints/endpoints.go b/common/endpoints/endpoints.go
index 90e3ac972..2b97e13e7 100644
--- a/common/endpoints/endpoints.go
+++ b/common/endpoints/endpoints.go
@@ -4,12 +4,14 @@ package endpoints
 
 import (
 	"bytes"
-	log "github.com/sirupsen/logrus"
+	"fmt"
 	"io"
 	"net/http"
 	"net/http/pprof"
 	"time"
 
+	log "github.com/sirupsen/logrus"
+
 	"github.com/twitter/scoot/common/stats"
 )
 
@@ -32,6 +34,10 @@ type TwitterServer struct {
 	Handlers map[string]http.Handler
 }
 
+func (s *TwitterServer) String() string {
+	return fmt.Sprintf("TwitterServer:Addr:%s, Stats:%+v, Handlers:%+v", s.Addr, s.Stats, s.Handlers)
+}
+
 func (s *TwitterServer) Serve() error {
 	mux := http.NewServeMux()
 	mux.HandleFunc("/", helpHandler)
diff --git a/config/scootconfig/cluster_modules.go b/config/scootconfig/cluster_modules.go
deleted file mode 100644
index cefb1acaf..000000000
--- a/config/scootconfig/cluster_modules.go
+++ /dev/null
@@ -1,44 +0,0 @@
-package scootconfig
-
-import (
-	"fmt"
-	"time"
-
-	"github.com/twitter/scoot/cloud/cluster"
-	"github.com/twitter/scoot/cloud/cluster/local"
-	"github.com/twitter/scoot/ice"
-)
-
-// Parameters for configuring an in-memory Scoot cluster
-// Count - number of in-memory workers
-type ClusterMemoryConfig struct {
-	Type  string
-	Count int
-}
-
-func (c *ClusterMemoryConfig) Install(bag *ice.MagicBag) {
-	bag.Put(c.Create)
-}
-
-func (c *ClusterMemoryConfig) Create() (*cluster.Cluster, error) {
-	workerNodes := make([]cluster.Node, c.Count)
-	for i := 0; i < c.Count; i++ {
-		workerNodes[i] = cluster.NewIdNode(fmt.Sprintf("inmemory%d", i))
-	}
-	return cluster.NewCluster(workerNodes, nil), nil
-}
-
-// Parameters for configuring a Scoot cluster that will have locally-run components.
-type ClusterLocalConfig struct {
-	Type string
-}
-
-func (c *ClusterLocalConfig) Install(bag *ice.MagicBag) {
-	bag.Put(c.Create)
-}
-
-func (c *ClusterLocalConfig) Create() (*cluster.Cluster, error) {
-	f := local.MakeFetcher("workerserver", "thrift_addr")
-	updates := cluster.MakeFetchCron(f, time.NewTicker(time.Second).C)
-	return cluster.NewCluster(nil, updates), nil
-}
diff --git a/config/scootconfig/saga_log_modules.go b/config/scootconfig/saga_log_modules.go
deleted file mode 100644
index 1d29d647c..000000000
--- a/config/scootconfig/saga_log_modules.go
+++ /dev/null
@@ -1,48 +0,0 @@
-package scootconfig
-
-import (
-	"time"
-
-	"github.com/twitter/scoot/ice"
-	"github.com/twitter/scoot/saga"
-	"github.com/twitter/scoot/saga/sagalogs"
-)
-
-// InMemorySagaLog struct is used by goice to create an InMemory instance
-// of the SagaLog interface.
-type InMemorySagaLogConfig struct {
-	Type          string
-	ExpirationSec int
-	GCIntervalSec int
-}
-
-// Adds the InMemorySagaLog Create function to the goice MagicBag
-func (c *InMemorySagaLogConfig) Install(bag *ice.MagicBag) {
-	bag.Put(c.Create)
-}
-
-// Creates an instance of an InMemorySagaLog
-func (c *InMemorySagaLogConfig) Create() saga.SagaLog {
-	return sagalogs.MakeInMemorySagaLog(
-		time.Duration(c.ExpirationSec)*time.Second,
-		time.Duration(c.GCIntervalSec)*time.Second)
-}
-
-// FileSagaLogConfig struct is used by goice to create a FileSagaLog
-// instance of the SagaLog interface
-// Directory specifies the name of the directory to store
-// Sagalog files in.
-type FileSagaLogConfig struct {
-	Type      string
-	Directory string
-}
-
-// Adds the FileSagaLogConfig Create function to the goice MagicBag
-func (c *FileSagaLogConfig) Install(bag *ice.MagicBag) {
-	bag.Put(c.Create)
-}
-
-// Creates an instance of the FileSagaLog
-func (c *FileSagaLogConfig) Create() (saga.SagaLog, error) {
-	return sagalogs.MakeFileSagaLog(c.Directory)
-}
diff --git a/config/scootconfig/scheduler_config_modules.go b/config/scootconfig/scheduler_config_modules.go
deleted file mode 100644
index 06f3037a5..000000000
--- a/config/scootconfig/scheduler_config_modules.go
+++ /dev/null
@@ -1,85 +0,0 @@
-package scootconfig
-
-import (
-	"strings"
-	"time"
-
-	"github.com/twitter/scoot/ice"
-	"github.com/twitter/scoot/scheduler/server"
-)
-
-//TODO(jschiller): make these configurable.
-
-// How long to keep retrying a runner req
-const DefaultRunnerRetryTimeout = 10 * time.Second
-
-// How long to sleep between runner req retries.
-const DefaultRunnerRetryInterval = time.Second
-
-// How long to wait between runner status queries to determine [init] status.
-const DefaultReadyFnBackoff = 5 * time.Second
-
-// Parameters to configure the Stateful Scheduler
-// MaxRetriesPerTask - the number of times to retry a failing task before
-//                     marking it as completed.
-// DebugMode - if true, starts the scheduler up but does not start
-//             the update loop.  Instead the loop must be advanced manually
-//             by calling step()
-// RecoverJobsOnStartup - if true, the scheduler recovers active sagas,
-//             from the sagalog, and restarts them.
-// DefaultTaskTimeout - default timeout for tasks, human readable ex: "30m"
-//
-// See server.SchedulerConfig for comments on the remaining fields.
-type StatefulSchedulerConfig struct {
-	Type                 string
-	MaxRetriesPerTask    int
-	DebugMode            bool
-	RecoverJobsOnStartup bool
-	DefaultTaskTimeout   string
-	TaskTimeoutOverhead  string
-	MaxRequestors        int
-	MaxJobsPerRequestor  int
-	Admins               string
-}
-
-func (c *StatefulSchedulerConfig) Install(bag *ice.MagicBag) {
-	bag.Put(c.Create)
-}
-
-func (c *StatefulSchedulerConfig) Create() (server.SchedulerConfig, error) {
-	var err error
-	var dtt time.Duration
-	if c.DefaultTaskTimeout != "" {
-		dtt, err = time.ParseDuration(c.DefaultTaskTimeout)
-		if err != nil {
-			return server.SchedulerConfig{}, err
-		}
-	}
-	var tto time.Duration
-	if c.TaskTimeoutOverhead != "" {
-		tto, err = time.ParseDuration(c.TaskTimeoutOverhead)
-		if err != nil {
-			return server.SchedulerConfig{}, err
-		}
-	}
-	admins := []string{}
-	for _, admin := range strings.Split(c.Admins, ",") {
-		if admin != "" {
-			admins = append(admins, admin)
-		}
-	}
-
-	return server.SchedulerConfig{
-		MaxRetriesPerTask:    c.MaxRetriesPerTask,
-		DebugMode:            c.DebugMode,
-		RecoverJobsOnStartup: c.RecoverJobsOnStartup,
-		DefaultTaskTimeout:   dtt,
-		TaskTimeoutOverhead:  tto,
-		RunnerRetryTimeout:   DefaultRunnerRetryTimeout,
-		RunnerRetryInterval:  DefaultRunnerRetryInterval,
-		ReadyFnBackoff:       DefaultReadyFnBackoff,
-		MaxRequestors:        c.MaxRequestors,
-		MaxJobsPerRequestor:  c.MaxJobsPerRequestor,
-		Admins:               admins,
-	}, nil
-}
diff --git a/runner/mocks/runner.go b/runner/mocks/runner.go
index 5cf2a3d2d..f2dcbb369 100644
--- a/runner/mocks/runner.go
+++ b/runner/mocks/runner.go
@@ -46,18 +46,6 @@ func (mr *MockServiceMockRecorder) Abort(arg0 interface{}) *gomock.Call {
 	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Abort", reflect.TypeOf((*MockService)(nil).Abort), arg0)
 }
 
-// Erase mocks base method
-func (m *MockService) Erase(arg0 runner.RunID) error {
-	ret := m.ctrl.Call(m, "Erase", arg0)
-	ret0, _ := ret[0].(error)
-	return ret0
-}
-
-// Erase indicates an expected call of Erase
-func (mr *MockServiceMockRecorder) Erase(arg0 interface{}) *gomock.Call {
-	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Erase", reflect.TypeOf((*MockService)(nil).Erase), arg0)
-}
-
 // Query mocks base method
 func (m *MockService) Query(arg0 runner.Query, arg1 runner.Wait) ([]runner.RunStatus, runner.ServiceStatus, error) {
 	ret := m.ctrl.Call(m, "Query", arg0, arg1)
diff --git a/scheduler/api/setup.go b/scheduler/api/setup.go
deleted file mode 100644
index 8ccf254dd..000000000
--- a/scheduler/api/setup.go
+++ /dev/null
@@ -1,168 +0,0 @@
-package api
-
-import (
-	"time"
-
-	"github.com/apache/thrift/lib/go/thrift"
-	log "github.com/sirupsen/logrus"
-
-	"github.com/twitter/scoot/bazel"
-	"github.com/twitter/scoot/bazel/execution"
-	"github.com/twitter/scoot/cloud/cluster"
-	"github.com/twitter/scoot/common/endpoints"
-	"github.com/twitter/scoot/common/stats"
-	"github.com/twitter/scoot/config/jsonconfig"
-	"github.com/twitter/scoot/config/scootconfig"
-	"github.com/twitter/scoot/ice"
-	"github.com/twitter/scoot/runner"
-	"github.com/twitter/scoot/saga"
-	"github.com/twitter/scoot/scheduler"
-	"github.com/twitter/scoot/scheduler/api/thrift/gen-go/scoot"
-	"github.com/twitter/scoot/scheduler/server"
-)
-
-type servers struct {
-	thrift thrift.TServer
-	http   *endpoints.TwitterServer
-	grpc   bazel.GRPCServer
-}
-
-func makeServers(
-	thrift thrift.TServer,
-	http *endpoints.TwitterServer,
-	grpc bazel.GRPCServer) servers {
-	return servers{thrift, http, grpc}
-}
-
-// Creates an MagicBag and a JsonSchema for this server and returns them
-func Defaults() (*ice.MagicBag, jsonconfig.Schema) {
-	bag := ice.NewMagicBag()
-	bag.PutMany(
-		func() (thrift.TServerTransport, error) { return thrift.NewTServerSocket(scheduler.DefaultSched_Thrift) },
-
-		func() thrift.TTransportFactory { return thrift.NewTTransportFactory() },
-
-		func() endpoints.StatScope { return "scheduler" },
-
-		func(scope endpoints.StatScope) stats.StatsReceiver {
-			return endpoints.MakeStatsReceiver(scope).Precision(time.Millisecond)
-		},
-
-		func(
-			cl *cluster.Cluster,
-			sc saga.SagaCoordinator,
-			rf func(cluster.Node) runner.Service,
-			config server.SchedulerConfig,
-			stat stats.StatsReceiver,
-			persistor server.Persistor,
-			durationKeyExtractorFn func(string) string,
-		) server.Scheduler {
-			return server.NewStatefulSchedulerFromCluster(cl, sc, rf, config, stat, persistor, durationKeyExtractorFn)
-		},
-
-		func(
-			s server.Scheduler,
-			sc saga.SagaCoordinator,
-			stat stats.StatsReceiver) scoot.CloudScoot {
-			return NewHandler(s, sc, stat)
-		},
-
-		func(
-			h scoot.CloudScoot,
-			t thrift.TServerTransport,
-			tf thrift.TTransportFactory,
-			pf thrift.TProtocolFactory) thrift.TServer {
-			return MakeServer(h, t, tf, pf)
-		},
-
-		func(s stats.StatsReceiver) *endpoints.TwitterServer {
-			return endpoints.NewTwitterServer(endpoints.Addr(scheduler.DefaultSched_HTTP), s, nil)
-		},
-
-		func(t thrift.TServer, h *endpoints.TwitterServer, g bazel.GRPCServer) servers {
-			return makeServers(t, h, g)
-		},
-
-		func(log saga.SagaLog) saga.SagaCoordinator {
-			return saga.MakeSagaCoordinator(log)
-		},
-
-		func() thrift.TProtocolFactory {
-			return thrift.NewTBinaryProtocolFactoryDefault()
-		},
-
-		func() *bazel.GRPCConfig {
-			return &bazel.GRPCConfig{
-				GRPCAddr: scheduler.DefaultSched_GRPC,
-			}
-		},
-
-		func(gc *bazel.GRPCConfig, s server.Scheduler, stat stats.StatsReceiver) bazel.GRPCServer {
-			return execution.MakeExecutionServer(gc, s, stat)
-		},
-	)
-
-	schema := jsonconfig.Schema(map[string]jsonconfig.Implementations{
-		"SagaLog": {
-			"memory": &scootconfig.InMemorySagaLogConfig{},
-			"file":   &scootconfig.FileSagaLogConfig{},
-			"":       &scootconfig.InMemorySagaLogConfig{},
-		},
-		"Cluster": {
-			"memory": &scootconfig.ClusterMemoryConfig{},
-			"local":  &scootconfig.ClusterLocalConfig{},
-			"": &scootconfig.ClusterMemoryConfig{
-				Type:  "memory",
-				Count: 10,
-			},
-		},
-		"Workers": {
-			"local": &scootconfig.WorkersLocalConfig{},
-			"rpc":   &scootconfig.WorkersThriftConfig{},
-			"":      &scootconfig.WorkersLocalConfig{Type: "local"},
-		},
-		"SchedulerConfig": {
-			"stateful": &scootconfig.StatefulSchedulerConfig{},
-			"": &scootconfig.StatefulSchedulerConfig{
-				Type:               "stateful",
-				MaxRetriesPerTask:  0,
-				DefaultTaskTimeout: "30m",
-			},
-		},
-	})
-
-	return bag, schema
-}
-
-// Starts the Server based on the MagicBag and config schema provided
-// this method blocks until the server completes running or an error occurs.
-func RunServer(bag *ice.MagicBag, schema jsonconfig.Schema, config []byte) {
-	// Parse Config
-	log.Info("scootapi/server RunServer(), config is:", string(config))
-	mod, err := schema.Parse(config)
-	if err != nil {
-		log.Fatal("Error configuring Scoot API: ", err)
-	}
-
-	// Initialize Objects Based on Config Settings
-	bag.InstallModule(mod)
-
-	// Run Servers
-	var servers servers
-	err = bag.Extract(&servers)
-	if err != nil {
-		log.Fatalf("Error injecting servers: %v", err)
-	}
-
-	errCh := make(chan error)
-	go func() {
-		errCh <- servers.http.Serve()
-	}()
-	go func() {
-		errCh <- servers.thrift.Serve()
-	}()
-	go func() {
-		errCh <- servers.grpc.Serve()
-	}()
-	log.Fatal("Error serving: ", <-errCh)
-}
diff --git a/scheduler/client/scootcl/main.go b/scheduler/client/scootcl/main.go
index 13c701bb6..532400bc4 100644
--- a/scheduler/client/scootcl/main.go
+++ b/scheduler/client/scootcl/main.go
@@ -3,9 +3,9 @@ package main
 import (
 	"github.com/apache/thrift/lib/go/thrift"
 	log "github.com/sirupsen/logrus"
+	"github.com/twitter/scoot/common"
 	"github.com/twitter/scoot/common/dialer"
 	"github.com/twitter/scoot/common/log/hooks"
-	"github.com/twitter/scoot/config/scootconfig"
 	"github.com/twitter/scoot/scheduler/client/cli"
 )
 
@@ -29,7 +29,7 @@ func main() {
 	transportFactory := thrift.NewTTransportFactory()
 	protocolFactory := thrift.NewTBinaryProtocolFactoryDefault()
 
-	di := dialer.NewSimpleDialer(transportFactory, protocolFactory, scootconfig.DefaultClientTimeout)
+	di := dialer.NewSimpleDialer(transportFactory, protocolFactory, common.DefaultClientTimeout)
 	cl, err := cli.NewSimpleCLIClient(di)
 	if err != nil {
 		log.Fatal("Failed to create new scoot CLI client: ", err)
diff --git a/scheduler/scheduler/config/config.go b/scheduler/scheduler/config/config.go
index fe31e1bc5..fdcb977ec 100644
--- a/scheduler/scheduler/config/config.go
+++ b/scheduler/scheduler/config/config.go
@@ -1,283 +1,173 @@
-// Code generated by go-bindata.
-// sources:
-// config/config.go
-// config/local.local
-// config/local.memory
-// DO NOT EDIT!
-
 package config
 
 import (
-	"bytes"
-	"compress/gzip"
+	"encoding/json"
 	"fmt"
-	"io"
-	"io/ioutil"
-	"os"
-	"path/filepath"
-	"strings"
 	"time"
-)
 
-func bindataRead(data []byte, name string) ([]byte, error) {
-	gz, err := gzip.NewReader(bytes.NewBuffer(data))
-	if err != nil {
-		return nil, fmt.Errorf("Read %q: %v", name, err)
-	}
+	log "github.com/sirupsen/logrus"
 
-	var buf bytes.Buffer
-	_, err = io.Copy(&buf, gz)
-	clErr := gz.Close()
+	"github.com/twitter/scoot/cloud/cluster"
+	"github.com/twitter/scoot/cloud/cluster/local"
+	"github.com/twitter/scoot/scheduler/server"
+	"github.com/twitter/scoot/workerapi/client"
+)
 
-	if err != nil {
-		return nil, fmt.Errorf("Read %q: %v", name, err)
-	}
-	if clErr != nil {
-		return nil, err
-	}
+// How long to keep retrying a runner req
+const DefaultRunnerRetryTimeout = 10 * time.Second
 
-	return buf.Bytes(), nil
-}
+// How long to sleep between runner req retries.
+const DefaultRunnerRetryInterval = time.Second
 
-type asset struct {
-	bytes []byte
-	info  os.FileInfo
-}
+// How long to wait between runner status queries to determine [init] status.
+const DefaultReadyFnBackoff = 5 * time.Second
 
-type bindataFileInfo struct {
-	name    string
-	size    int64
-	mode    os.FileMode
-	modTime time.Time
+// SchedulerServerConfig config structure holding original json configs
+type JSONConfigs struct {
+	Cluster   ClusterJSONConfig              `json:"Cluster"`
+	Workers   client.WorkersClientJSONConfig `json:"Workers"`
+	Scheduler SchedulerJSONConfig            `json:"SchedulerConfig"`
+	SagaLog   SagaLogJSONConfig              `json:"SagaLog"`
 }
 
-func (fi bindataFileInfo) Name() string {
-	return fi.name
-}
-func (fi bindataFileInfo) Size() int64 {
-	return fi.size
-}
-func (fi bindataFileInfo) Mode() os.FileMode {
-	return fi.mode
-}
-func (fi bindataFileInfo) ModTime() time.Time {
-	return fi.modTime
-}
-func (fi bindataFileInfo) IsDir() bool {
-	return false
-}
-func (fi bindataFileInfo) Sys() interface{} {
-	return nil
+func (s JSONConfigs) String() string {
+	return fmt.Sprintf("\n%s\n%s\n%s\n%s", s.Cluster, s.Workers, s.Scheduler, s.SagaLog)
 }
 
-var _configConfigGo = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x01\x00\x00\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00")
-
-func configConfigGoBytes() ([]byte, error) {
-	return bindataRead(
-		_configConfigGo,
-		"config/config.go",
-	)
+type ClusterJSONConfig struct {
+	Type  string `json:"Type"`  // cluster type: local, memory
+	Count int    `json:"Count"` // default to 10 for Type == memory
 }
 
-func configConfigGo() (*asset, error) {
-	bytes, err := configConfigGoBytes()
-	if err != nil {
-		return nil, err
-	}
-
-	info := bindataFileInfo{name: "config/config.go", size: 0, mode: os.FileMode(420), modTime: time.Unix(1583878394, 0)}
-	a := &asset{bytes: bytes, info: info}
-	return a, nil
+func (c ClusterJSONConfig) String() string {
+	return fmt.Sprintf("ClusterJSONConfig: Type: %s, Count: %d", c.Type, c.Count)
 }
 
-var _configLocalLocal = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x6c\x8e\x41\x4b\x03\x31\x10\x46\xef\xfb\x2b\x42\xce\x45\x8b\xe2\x65\xaf\xed\x49\x2c\x2e\xed\x82\xe7\x69\x76\x12\x43\x67\x77\x96\x99\x89\x58\xa4\xff\x5d\xa2\xad\x0a\xf5\x98\x79\x2f\x8f\xef\xa3\x71\xce\xaf\xa8\xa8\xa1\xf8\xd6\xd5\xa7\x73\xbe\x3f\xce\xe8\x5b\xe7\x89\x03\x90\x6f\x9c\x3b\x2d\xaa\xf7\xc2\x72\x40\xd1\x6b\x4f\xe6\xe0\x17\xdf\xa7\x8e\x89\xf2\x94\x3a\x94\xcc\x43\x65\x77\x0f\xcb\x51\x7f\x1b\xbb\xf0\x8a\x43\x21\x94\x15\x4f\x31\xa7\xeb\x96\x1a\x18\xc6\x42\x97\xe0\x06\xde\xb7\x68\x92\x51\x3b\x94\x1e\xf4\xe0\x5d\xeb\x96\x67\xb8\xc6\x7d\x49\x1b\x1e\xb0\x1e\x23\x90\xe2\x19\x6c\x31\xf0\x1b\xca\x23\xef\xf5\x79\xda\x19\x88\x95\xb9\x3a\x26\x05\x7f\xfe\x46\x28\x64\x35\xd9\xe7\x11\xb9\x58\x15\xfc\xfd\x72\xfc\xb3\x16\x12\x3c\xf1\x3f\x2b\x63\x26\xbc\x2c\x5c\x67\xc1\x60\x2c\xc7\x0a\x6e\x34\x30\xdb\x00\x06\xb7\xd5\x51\x48\x40\x9c\xbe\x8a\xcd\xa9\xf9\x0c\x00\x00\xff\xff\x1b\xaf\xe8\xca\x6f\x01\x00\x00")
-
-func configLocalLocalBytes() ([]byte, error) {
-	return bindataRead(
-		_configLocalLocal,
-		"config/local.local",
-	)
+type SagaLogJSONConfig struct {
+	Type          string `json:"Type"`          // file
+	Directory     string `json:"Directory"`     // default to .scootdata/filesagalog
+	ExpirationSec int    `json:"ExpirationSec"` // default to 0
+	GCIntervalSec int    `json:"GCIntervalSec"` // default to 1
 }
 
-func configLocalLocal() (*asset, error) {
-	bytes, err := configLocalLocalBytes()
-	if err != nil {
-		return nil, err
-	}
-
-	info := bindataFileInfo{name: "config/local.local", size: 367, mode: os.FileMode(420), modTime: time.Unix(1571853409, 0)}
-	a := &asset{bytes: bytes, info: info}
-	return a, nil
+func (s SagaLogJSONConfig) String() string {
+	return fmt.Sprintf("SagaLogJSONConfig: Type:%s, Directory: %s, ExpirationSec: %d, GCIntervalSec: %d",
+		s.Type, s.Directory, s.ExpirationSec, s.GCIntervalSec)
 }
 
-var _configLocalMemory = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x6c\x8f\xcd\x6a\xc3\x30\x10\x84\xef\x7e\x8a\x65\xcf\x3d\x38\xf4\xe6\xab\x53\x4a\x4b\x43\x4b\xec\x17\xd8\x38\x63\x57\x54\x96\xcc\x6a\x15\x12\x4a\xde\xbd\x88\xa4\x84\xfe\x1c\xf7\x9b\xe1\x63\xf6\xb3\x22\xe2\xd6\xe7\x64\x50\x6e\xa8\x9c\x44\xdc\x9f\x16\x70\x43\x3c\x63\x8e\x7a\xe2\xbb\x0b\x6d\x63\x0e\xc6\x0d\xad\xea\x8a\xe8\x5c\x20\x77\xc3\x3b\xf6\xd9\x43\xdb\x18\x46\x37\xfd\x35\x24\x13\xc3\x98\xfd\xb7\x63\x23\xc7\x2d\x4c\x1d\xd2\x1b\xb4\x97\xf4\xc1\xd4\x50\x7d\x0d\xd7\xd8\xe5\x69\x13\xf7\x28\x70\x14\x9f\x70\x0d\xb6\x18\xe2\x01\xfa\x1c\x77\xe9\x35\x74\x26\x6a\x79\xf9\xdd\x59\x63\x94\xec\xad\x38\x7b\x37\x23\x66\x2b\x0d\xbe\xaf\x67\xbe\xcd\x95\x49\x5e\xe2\x3f\x33\x7f\x3e\xfa\x70\x5c\x9c\x8a\xb9\x18\x3a\x0c\x7c\xdb\xf7\xd8\x3e\x05\x83\x1e\xc4\x5f\xf8\xaa\x88\xab\x73\xf5\x15\x00\x00\xff\xff\x6f\xcc\x0c\x91\x45\x01\x00\x00")
+type SchedulerJSONConfig struct {
+	Type                 string `json:"Type"`              // scheduler type: stateful
+	MaxRetriesPerTask    int    `json:"MaxRetriesPerTask"` // default to 0
+	MaxRequestors        int    `json:"MaxRequestors"`
+	MaxJobsPerRequestor  int    `json:"MaxJobsPerRequestor"`
+	DebugMode            bool   `json:"DebugMode"`            // default to false
+	RecoverJobsOnStartup bool   `json:"RecoverJobsOnStartup"` // default to true
+	DefaultTaskTimeout   string `json:"DefaultTaskTimeout"`   // default to 30m
+}
 
-func configLocalMemoryBytes() ([]byte, error) {
-	return bindataRead(
-		_configLocalMemory,
-		"config/local.memory",
-	)
+func (sc SchedulerJSONConfig) String() string {
+	return fmt.Sprintf("SchedulerJSONConfig: Type: %s, MaxRetriesPerTask: %d, MaxRequestors: %d, MaxJobsPerRequestor: %d, DebugMode: %t, "+
+		"RecoverJobsOnStartup: %t, DefaultTaskTimeout: %s",
+		sc.Type, sc.MaxRetriesPerTask, sc.MaxRequestors, sc.MaxJobsPerRequestor, sc.DebugMode, sc.RecoverJobsOnStartup, sc.DefaultTaskTimeout)
 }
 
-func configLocalMemory() (*asset, error) {
-	bytes, err := configLocalMemoryBytes()
-	if err != nil {
-		return nil, err
+func GetConfigText(configSelector string) ([]byte, error) {
+	configText, ok := SchedulerConfigs[configSelector]
+	if !ok {
+		keys := make([]string, 0, len(SchedulerConfigs))
+		for k := range SchedulerConfigs {
+			keys = append(keys, k)
+		}
+		return nil, fmt.Errorf("invalid configuration %s, supported values are %v", configSelector, keys)
 	}
 
-	info := bindataFileInfo{name: "config/local.memory", size: 325, mode: os.FileMode(420), modTime: time.Unix(1571853409, 0)}
-	a := &asset{bytes: bytes, info: info}
-	return a, nil
+	return []byte(configText), nil
 }
 
-// Asset loads and returns the asset for the given name.
-// It returns an error if the asset could not be found or
-// could not be loaded.
-func Asset(name string) ([]byte, error) {
-	cannonicalName := strings.Replace(name, "\\", "/", -1)
-	if f, ok := _bindata[cannonicalName]; ok {
-		a, err := f()
+func (jc *SchedulerJSONConfig) CreateSchedulerConfig() (*server.SchedulerConfiguration, error) {
+	var err error
+	serverConfig := &server.SchedulerConfiguration{}
+	if jc.DefaultTaskTimeout != "" {
+		serverConfig.DefaultTaskTimeout, err = time.ParseDuration(jc.DefaultTaskTimeout)
 		if err != nil {
-			return nil, fmt.Errorf("Asset %s can't read by error: %v", name, err)
+			return nil, err
 		}
-		return a.bytes, nil
 	}
-	return nil, fmt.Errorf("Asset %s not found", name)
-}
 
-// MustAsset is like Asset but panics when Asset would return an error.
-// It simplifies safe initialization of global variables.
-func MustAsset(name string) []byte {
-	a, err := Asset(name)
+	serverConfig.MaxRetriesPerTask = jc.MaxRetriesPerTask
+	serverConfig.DebugMode = jc.DebugMode
+	serverConfig.RecoverJobsOnStartup = jc.RecoverJobsOnStartup
+	serverConfig.RunnerRetryTimeout = DefaultRunnerRetryTimeout
+	serverConfig.RunnerRetryInterval = DefaultRunnerRetryInterval
+	serverConfig.ReadyFnBackoff = DefaultReadyFnBackoff
+	serverConfig.MaxRequestors = jc.MaxRequestors
+	serverConfig.MaxJobsPerRequestor = jc.MaxJobsPerRequestor
+	return serverConfig, nil
+}
+
+// GetSchedulerConfig get the scheduler config
+func GetSchedulerConfigs(configName string) (*JSONConfigs, error) {
+	// get the default values, these will override any of the config
+	// sections whose Type is ""
+	defaultConfigText, _ := GetConfigText("default")
+	defaultConfig := &JSONConfigs{}
+	err := json.Unmarshal(defaultConfigText, &defaultConfig)
 	if err != nil {
-		panic("asset: Asset(" + name + "): " + err.Error())
+		return nil, fmt.Errorf("couldn't parse the default config: %v", err)
 	}
 
-	return a
-}
-
-// AssetInfo loads and returns the asset info for the given name.
-// It returns an error if the asset could not be found or
-// could not be loaded.
-func AssetInfo(name string) (os.FileInfo, error) {
-	cannonicalName := strings.Replace(name, "\\", "/", -1)
-	if f, ok := _bindata[cannonicalName]; ok {
-		a, err := f()
-		if err != nil {
-			return nil, fmt.Errorf("AssetInfo %s can't read by error: %v", name, err)
-		}
-		return a.info, nil
+	// get the config values as per the command line config name
+	configText, err := GetConfigText(configName)
+	if err != nil {
+		return nil, err
 	}
-	return nil, fmt.Errorf("AssetInfo %s not found", name)
-}
 
-// AssetNames returns the names of the assets.
-func AssetNames() []string {
-	names := make([]string, 0, len(_bindata))
-	for name := range _bindata {
-		names = append(names, name)
+	schedServerConfig := &JSONConfigs{}
+	err = json.Unmarshal(configText, &schedServerConfig)
+	if err != nil {
+		return nil, fmt.Errorf("couldn't parse top-level config: %v", err)
 	}
-	return names
-}
-
-// _bindata is a table, holding each asset generator, mapped to its name.
-var _bindata = map[string]func() (*asset, error){
-	"config/config.go":    configConfigGo,
-	"config/local.local":  configLocalLocal,
-	"config/local.memory": configLocalMemory,
-}
 
-// AssetDir returns the file names below a certain
-// directory embedded in the file by go-bindata.
-// For example if you run go-bindata on data/... and data contains the
-// following hierarchy:
-//     data/
-//       foo.txt
-//       img/
-//         a.png
-//         b.png
-// then AssetDir("data") would return []string{"foo.txt", "img"}
-// AssetDir("data/img") would return []string{"a.png", "b.png"}
-// AssetDir("foo.txt") and AssetDir("notexist") would return an error
-// AssetDir("") will return []string{"data"}.
-func AssetDir(name string) ([]string, error) {
-	node := _bintree
-	if len(name) != 0 {
-		cannonicalName := strings.Replace(name, "\\", "/", -1)
-		pathList := strings.Split(cannonicalName, "/")
-		for _, p := range pathList {
-			node = node.Children[p]
-			if node == nil {
-				return nil, fmt.Errorf("Asset %s not found", name)
-			}
-		}
+	// use the default values for any sections whose type was not set in the command line config
+	if schedServerConfig.Cluster.Type == "" {
+		log.Infof("using default Cluster config")
+		schedServerConfig.Cluster = defaultConfig.Cluster
 	}
-	if node.Func != nil {
-		return nil, fmt.Errorf("Asset %s not found", name)
+	if schedServerConfig.SagaLog.Type == "" {
+		log.Infof("using default SagaLog config")
+		schedServerConfig.SagaLog = defaultConfig.SagaLog
 	}
-	rv := make([]string, 0, len(node.Children))
-	for childName := range node.Children {
-		rv = append(rv, childName)
+	if schedServerConfig.Workers.Type == "" {
+		log.Infof("using default Workers config")
+		schedServerConfig.Workers = defaultConfig.Workers
+	}
+	if schedServerConfig.Scheduler.Type == "" {
+		log.Infof("using default Scheduler config")
+		schedServerConfig.Scheduler = defaultConfig.Scheduler
 	}
-	return rv, nil
-}
 
-type bintree struct {
-	Func     func() (*asset, error)
-	Children map[string]*bintree
+	return schedServerConfig, nil
 }
 
-var _bintree = &bintree{nil, map[string]*bintree{
-	"config": {nil, map[string]*bintree{
-		"config.go":    {configConfigGo, map[string]*bintree{}},
-		"local.local":  {configLocalLocal, map[string]*bintree{}},
-		"local.memory": {configLocalMemory, map[string]*bintree{}},
-	}},
-}}
-
-// RestoreAsset restores an asset under the given directory
-func RestoreAsset(dir, name string) error {
-	data, err := Asset(name)
-	if err != nil {
-		return err
-	}
-	info, err := AssetInfo(name)
-	if err != nil {
-		return err
-	}
-	err = os.MkdirAll(_filePath(dir, filepath.Dir(name)), os.FileMode(0755))
-	if err != nil {
-		return err
-	}
-	err = ioutil.WriteFile(_filePath(dir, name), data, info.Mode())
-	if err != nil {
-		return err
-	}
-	err = os.Chtimes(_filePath(dir, name), info.ModTime(), info.ModTime())
-	if err != nil {
-		return err
-	}
-	return nil
+// Parameters for configuring an in-memory Scoot cluster
+// Count - number of in-memory workers
+type ClusterMemoryConfig struct {
+	Count int
 }
 
-// RestoreAssets restores an asset under the given directory recursively
-func RestoreAssets(dir, name string) error {
-	children, err := AssetDir(name)
-	// File
-	if err != nil {
-		return RestoreAsset(dir, name)
+func (c *ClusterMemoryConfig) Create() (*cluster.Cluster, error) {
+	workerNodes := make([]cluster.Node, c.Count)
+	for i := 0; i < c.Count; i++ {
+		workerNodes[i] = cluster.NewIdNode(fmt.Sprintf("inmemory%d", i))
 	}
-	// Dir
-	for _, child := range children {
-		err = RestoreAssets(dir, filepath.Join(name, child))
-		if err != nil {
-			return err
-		}
-	}
-	return nil
+	return cluster.NewCluster(workerNodes, nil), nil
 }
 
-func _filePath(dir, name string) string {
-	cannonicalName := strings.Replace(name, "\\", "/", -1)
-	return filepath.Join(append([]string{dir}, strings.Split(cannonicalName, "/")...)...)
+// Parameters for configuring a Scoot cluster that will have locally-run components.
+type ClusterLocalConfig struct{}
+
+func (c *ClusterLocalConfig) Create() (*cluster.Cluster, error) {
+	f := local.MakeFetcher("workerserver", "thrift_addr")
+	updates := cluster.MakeFetchCron(f, time.NewTicker(time.Second).C)
+	return cluster.NewCluster(nil, updates), nil
 }
diff --git a/scheduler/scheduler/config/configs.go b/scheduler/scheduler/config/configs.go
new file mode 100644
index 000000000..5df2b5dda
--- /dev/null
+++ b/scheduler/scheduler/config/configs.go
@@ -0,0 +1,74 @@
+package config
+
+// SchedulerConfigs the map of available configurations
+var SchedulerConfigs = map[string]string{
+	"default":      defaultConfig,
+	"local.local":  localLocal,
+	"local.memory": localMemory,
+}
+
+// defaultConfig the configuration values that are used for nil parts of a specific configuration
+const defaultConfig = `
+{
+	"Cluster": {
+	  "Type": "memory"
+	},
+	"Workers": {
+	  "Type": "local"
+	},
+	"SchedulerConfig": {
+	  "Type": "stateful",
+	  "MaxRetriesPerTask" : 0,
+	  "DefaultTaskTimeout" : "30m"
+	},
+	"SagaLog": {
+	  "Type": "memory"
+	}
+}
+`
+
+// localLocal config for local.local - !!! make sure this constant is added to SchedulerConfigs map above !!!
+const localLocal = `
+{
+	"Cluster": {
+	  "Type": "local"
+	},
+	"Workers": {
+	  "Type": "rpc",
+	  "PollingPeriod": "250ms"
+	},
+	"SchedulerConfig": {
+	  "Type": "stateful",
+	  "MaxRetriesPerTask" : 0,
+	  "DebugMode" : false,
+	  "RecoverJobsOnStartup" : true,
+	  "DefaultTaskTimeout" : "30m"
+	},
+	"SagaLog": {
+	  "Type": "file",
+	  "Directory": ".scootdata/filesagalog"
+	}
+  }
+  `
+
+// localMemory config for local.memory - !!! make sure this constant is added to SchedulerConfigs map above !!!
+const localMemory = `
+  {
+	"Cluster": {
+	  "Type": "memory",
+	  "Count": 10
+	},
+	"SchedulerConfig": {
+	  "Type": "stateful",
+	  "MaxRetriesPerTask" : 0,
+	  "DebugMode" : false,
+	  "RecoverJobsOnStartup" : false,
+	  "DefaultTaskTimeout" : "30m"
+	},
+	"SagaLog": {
+	  "Type": "memory",
+	  "ExpirationSec": 0,
+	  "GCIntervalSec": 1
+	}
+  }
+  `
diff --git a/scheduler/scheduler/config/local.local b/scheduler/scheduler/config/local.local
deleted file mode 100644
index d5f03a577..000000000
--- a/scheduler/scheduler/config/local.local
+++ /dev/null
@@ -1,20 +0,0 @@
-{
-  "Cluster": {
-    "Type": "local"
-  },
-  "Workers": {
-    "Type": "rpc",
-    "PollingPeriod": "250ms"
-  },
-  "SchedulerConfig": {
-    "Type": "stateful",
-    "MaxRetriesPerTask" : 0,
-    "DebugMode" : false,
-    "RecoverJobsOnStartup" : true,
-    "DefaultTaskTimeout" : "30m"
-  },
-  "SagaLog": {
-    "Type": "file",
-    "Directory": ".scootdata/filesagalog"
-  }
-}
diff --git a/scheduler/scheduler/config/local.memory b/scheduler/scheduler/config/local.memory
deleted file mode 100644
index 080ae1d1b..000000000
--- a/scheduler/scheduler/config/local.memory
+++ /dev/null
@@ -1,18 +0,0 @@
-{
-  "Cluster": {
-    "Type": "memory",
-    "Count": 10
-  },
-  "SchedulerConfig": {
-    "Type": "stateful",
-    "MaxRetriesPerTask" : 0,
-    "DebugMode" : false,
-    "RecoverJobsOnStartup" : false,
-    "DefaultTaskTimeout" : "30m"
-  },
-  "SagaLog": {
-    "Type": "memory",
-    "ExpirationSec": 0,
-    "GCIntervalSec": 1
-  }
-}
diff --git a/scheduler/scheduler/main.go b/scheduler/scheduler/main.go
index f581751aa..a8f61d8d5 100644
--- a/scheduler/scheduler/main.go
+++ b/scheduler/scheduler/main.go
@@ -1,27 +1,25 @@
 package main
 
-//go:generate go-bindata -pkg "config" -o ./config/config.go config
-//go:generate go fmt ./config/config.go
-
 import (
 	"flag"
+	"time"
 
 	"github.com/apache/thrift/lib/go/thrift"
 	log "github.com/sirupsen/logrus"
 
 	"github.com/twitter/scoot/bazel"
+	"github.com/twitter/scoot/common"
 	"github.com/twitter/scoot/common/endpoints"
 	"github.com/twitter/scoot/common/log/hooks"
-	"github.com/twitter/scoot/common/stats"
-	"github.com/twitter/scoot/config/jsonconfig"
-	"github.com/twitter/scoot/config/scootconfig"
 	"github.com/twitter/scoot/scheduler"
-	"github.com/twitter/scoot/scheduler/api"
 	"github.com/twitter/scoot/scheduler/scheduler/config"
-	"github.com/twitter/scoot/scheduler/server"
-	"io/ioutil"
+	"github.com/twitter/scoot/scheduler/starter"
 )
 
+func nopDurationKeyExtractor(id string) string {
+	return id
+}
+
 func main() {
 	log.AddHook(hooks.NewContextHook())
 
@@ -40,55 +38,43 @@ func main() {
 
 	level, err := log.ParseLevel(*logLevelFlag)
 	if err != nil {
-		log.Error(err)
-		return
+		log.Fatal(err)
 	}
 	log.SetLevel(level)
 
-	configText, err := jsonconfig.GetConfigText(*configFlag, config.Asset)
+	schedulerJSONConfigs, err := config.GetSchedulerConfigs(*configFlag)
 	if err != nil {
-		log.Fatal(err)
+		log.Fatalf("error parsing schedule server config.  Scheduler not started. %s", err)
+	}
+	schedulerConfig, err := schedulerJSONConfigs.Scheduler.CreateSchedulerConfig()
+	if err != nil {
+		log.Fatalf("error creating schedule server config.  Scheduler not started. %s", err)
 	}
-	bag, schema := api.Defaults()
-	bag.PutMany(
-		func() (thrift.TServerTransport, error) {
-			return thrift.NewTServerSocket(*thriftAddr)
-		},
-
-		func() scootconfig.ClientTimeout {
-			return scootconfig.ClientTimeout(scootconfig.DefaultClientTimeout)
-		},
-
-		func(s stats.StatsReceiver) *endpoints.TwitterServer {
-			return endpoints.NewTwitterServer(endpoints.Addr(*httpAddr), s, nil)
-		},
 
-		func() *bazel.GRPCConfig {
-			return &bazel.GRPCConfig{
-				GRPCAddr:          *grpcAddr,
-				ListenerMaxConns:  *grpcConns,
-				RateLimitPerSec:   *grpcRate,
-				BurstLimitPerSec:  *grpcBurst,
-				ConcurrentStreams: *grpcStreams,
-				MaxConnIdleMins:   *grpcIdleMins,
-			}
-		},
+	thriftServerSocket, err := thrift.NewTServerSocket(*thriftAddr)
+	if err != nil {
+		log.Fatalf("error creating thrift server socket.  Scheduler not started. %s", err)
+	}
 
-		func() (string, error) {
-			return ioutil.TempDir("", "sched")
-		},
+	statsReceiver := endpoints.MakeStatsReceiver("scheduler").Precision(time.Millisecond)
+	httpServer := endpoints.NewTwitterServer(endpoints.Addr(*httpAddr), statsReceiver, nil)
 
-		func() server.Persistor {
-			return nil
-		},
+	bazelGRPCConfig := &bazel.GRPCConfig{
+		GRPCAddr:          *grpcAddr,
+		ListenerMaxConns:  *grpcConns,
+		RateLimitPerSec:   *grpcRate,
+		BurstLimitPerSec:  *grpcBurst,
+		ConcurrentStreams: *grpcStreams,
+		MaxConnIdleMins:   *grpcIdleMins,
+	}
 
-		func() func(string) string { // noop for extracting duration id from task id
-			return func(id string) string {
-				return id
-			}
-		},
-	)
+	cluster, err := starter.GetCluster(schedulerJSONConfigs.Cluster)
+	if err != nil {
+		log.Fatalf("%s. Scheduler not started", err)
+	}
 
-	log.Info("Starting Cloud Scoot API Server & Scheduler on", *thriftAddr)
-	api.RunServer(bag, schema, configText)
+	log.Infof("Starting Cloud Scoot API Server & Scheduler on %s with %s", *thriftAddr, *configFlag)
+	starter.StartServer(*schedulerConfig, schedulerJSONConfigs.SagaLog, schedulerJSONConfigs.Workers,
+		thriftServerSocket, &statsReceiver, common.DefaultClientTimeout, httpServer, bazelGRPCConfig,
+		nil, nopDurationKeyExtractor, cluster)
 }
diff --git a/scheduler/server/cluster_state.go b/scheduler/server/cluster_state.go
index a111237a3..e483dc27d 100644
--- a/scheduler/server/cluster_state.go
+++ b/scheduler/server/cluster_state.go
@@ -210,7 +210,7 @@ func (c *clusterState) getNodeState(nodeId cluster.NodeId) (*nodeState, bool) {
 	return ns, ok
 }
 
-// upate cluster state to reflect added and removed nodes
+// update cluster state to reflect added and removed nodes
 func (c *clusterState) updateCluster() {
 	defer c.stats.Latency(stats.SchedUpdateClusterLatency_ms).Time().Stop()
 	select {
@@ -363,6 +363,13 @@ func (c *clusterState) update(updates []cluster.NodeUpdate) {
 		}
 	}
 
+	if adds > 0 || removals > 0 {
+		log.Infof("Number of nodes added: %d\nNumber of nodes removed: %d, num iterations without change: %d. %s", adds, removals, c.nopUpdateCnt, c.status())
+		c.nopUpdateCnt = 0
+	} else {
+		c.nopUpdateCnt++
+	}
+
 	c.stats.Gauge(stats.ClusterAvailableNodes).Update(int64(len(c.nodes)))
 	c.stats.Gauge(stats.ClusterFreeNodes).Update(int64(c.numFree()))
 	c.stats.Gauge(stats.ClusterRunningNodes).Update(int64(c.numRunning))
diff --git a/scheduler/server/stateful_scheduler.go b/scheduler/server/stateful_scheduler.go
index b9aaf313f..0a18dd563 100644
--- a/scheduler/server/stateful_scheduler.go
+++ b/scheduler/server/stateful_scheduler.go
@@ -95,7 +95,7 @@ func nopDurationKeyExtractor(key string) string {
 	return key
 }
 
-// Scheduler Config variables read at initialization
+// SchedulerConfiguration variables read at initialization
 // MaxRetriesPerTask - the number of times to retry a failing task before
 //     marking it as completed.
 // DebugMode - if true, starts the scheduler up but does not start
@@ -116,7 +116,7 @@ func nopDurationKeyExtractor(key string) string {
 // TaskThrottle -
 //	   requestors will try not to schedule jobs that make the scheduler exceed
 //     the TaskThrottle.  Note: Sickle may exceed it with retries.
-type SchedulerConfig struct {
+type SchedulerConfiguration struct {
 	MaxRetriesPerTask    int
 	DebugMode            bool
 	RecoverJobsOnStartup bool
@@ -134,6 +134,14 @@ type SchedulerConfig struct {
 	SchedAlg       SchedulingAlgorithm
 }
 
+func (sc *SchedulerConfiguration) String() string {
+	return fmt.Sprintf("SchedulerConfiguration: MaxRetriesPerTask: %d, DebugMode: %t, RecoverJobsOnStartup: %t, DefaultTaskTimeout: %s, "+
+		"TaskTimeoutOverhead: %s, RunnerRetryTimeout: %s, RunnerRetryInterval: %s, MaxRequestors: %d, MaxJobsPerRequestor: %d, TaskThrottle: %d, "+
+		"Admins: %v",
+		sc.MaxRetriesPerTask, sc.DebugMode, sc.RecoverJobsOnStartup, sc.DefaultTaskTimeout, sc.TaskTimeoutOverhead, sc.RunnerRetryTimeout,
+		sc.RunnerRetryInterval, sc.MaxRequestors, sc.MaxJobsPerRequestor, sc.TaskThrottle, sc.Admins)
+}
+
 // Used to keep a running average of duration for a specific task.
 type averageDuration struct {
 	count    int64
@@ -158,7 +166,7 @@ type RunnerFactory func(node cluster.Node) runner.Service
 // The callbacks are executed as part of the scheduler loop.  They therefore can
 // safely read & modify the scheduler state.
 type statefulScheduler struct {
-	config        *SchedulerConfig
+	config        *SchedulerConfiguration
 	sagaCoord     saga.SagaCoordinator
 	runnerFactory RunnerFactory
 	asyncRunner   async.Runner
@@ -187,6 +195,13 @@ type statefulScheduler struct {
 
 	// durationKeyExtractorFn - function to extract, from taskID, the key to use for tracking task average durations
 	durationKeyExtractorFn func(string) string
+
+	SchedAlg SchedulingAlgorithm
+}
+
+func (s *statefulScheduler) String() string {
+	return fmt.Sprintf("%s, num nodes: %d, num suspended nodes: %d, maxFlakyDuration: %s, maxLostDuration: %s",
+		s.config, len(s.clusterState.nodes), len(s.clusterState.suspendedNodes), s.clusterState.maxFlakyDuration, s.clusterState.maxLostDuration)
 }
 
 // contains jobId to be killed and callback for the result of processing the request
@@ -205,7 +220,7 @@ func NewStatefulSchedulerFromCluster(
 	cl *cluster.Cluster,
 	sc saga.SagaCoordinator,
 	rf RunnerFactory,
-	config SchedulerConfig,
+	config SchedulerConfiguration,
 	stat stats.StatsReceiver,
 	persistor Persistor,
 	durationKeyExtractorFn func(string) string,
@@ -234,7 +249,7 @@ func NewStatefulScheduler(
 	clusterUpdates chan []cluster.NodeUpdate,
 	sc saga.SagaCoordinator,
 	rf RunnerFactory,
-	config SchedulerConfig,
+	config SchedulerConfiguration,
 	stat stats.StatsReceiver,
 	persistor Persistor,
 	durationKeyExtractorFn func(string) string) *statefulScheduler {
@@ -346,6 +361,8 @@ func NewStatefulScheduler(
 	}
 	sched.loadSettings()
 
+	log.Info(sched)
+
 	if !config.DebugMode {
 		// start the scheduler loop
 		log.Info("Starting scheduler loop")
diff --git a/scheduler/starter/modules.go b/scheduler/starter/modules.go
new file mode 100644
index 000000000..39646de88
--- /dev/null
+++ b/scheduler/starter/modules.go
@@ -0,0 +1,183 @@
+package starter
+
+import (
+	"fmt"
+	"net"
+	"os"
+	"time"
+
+	"github.com/apache/thrift/lib/go/thrift"
+	log "github.com/sirupsen/logrus"
+	"golang.org/x/net/proxy"
+
+	"github.com/twitter/scoot/cloud/cluster"
+	"github.com/twitter/scoot/common"
+	"github.com/twitter/scoot/common/dialer"
+	"github.com/twitter/scoot/runner"
+	"github.com/twitter/scoot/runner/runners"
+	"github.com/twitter/scoot/saga"
+	"github.com/twitter/scoot/saga/sagalogs"
+	"github.com/twitter/scoot/scheduler/scheduler/config"
+	"github.com/twitter/scoot/scheduler/server"
+	"github.com/twitter/scoot/workerapi/client"
+)
+
+const DEFAULT_SOCKS_PORT = "50001"
+const DEFAULT_SOCKS_ADDR = "localhost:" + DEFAULT_SOCKS_PORT
+
+func GetWorkerRunnerServiceFn(workers client.WorkersClientJSONConfig, thriftTransportFactory thrift.TTransportFactory, binaryProtocolFactory thrift.TProtocolFactory) (func(cluster.Node) runner.Service, error) {
+	var rf func(cluster.Node) runner.Service
+	var err error
+	if workers.Type == "socks" {
+		rf, err = GetSocksWorker()
+	} else {
+		rf, err = client.NewWorkerThriftClient(thriftTransportFactory, binaryProtocolFactory, common.DefaultClientTimeout, workers)
+	}
+	if err != nil {
+		return nil, fmt.Errorf("error creating worker thrift client (runner.Service). %s", err)
+	}
+
+	return rf, nil
+}
+
+func GetSocksWorker() (server.RunnerFactory, error) {
+	transportFactory, err := NewTTransportFactory()
+	if err != nil {
+		return nil, err
+	}
+	protocolFactory := thrift.NewTBinaryProtocolFactoryDefault()
+
+	wf := func(node cluster.Node) runner.Service {
+		di := dialer.NewSimpleDialer(transportFactory, protocolFactory, common.DefaultClientTimeout)
+		cl, _ := client.NewSimpleClient(di, string(node.Id()))
+		return runners.NewPollingService(cl, cl, 250*time.Millisecond)
+	}
+
+	return wf, nil
+}
+
+func GetProxyAddr() string {
+	port := os.Getenv("SOCKS_PORT")
+	if port != "" {
+		return "localhost:" + port
+	}
+	return ""
+}
+
+func GetProxyDialer(proxyAddr string) (proxy.Dialer, error) {
+	return proxy.SOCKS5("tcp", proxyAddr, nil, proxy.Direct)
+}
+
+func NewTTransportFactory() (thrift.TTransportFactory, error) {
+	addr := GetProxyAddr()
+	if addr == "" {
+		addr = DEFAULT_SOCKS_ADDR
+	}
+	dialer, err := GetProxyDialer(addr)
+	if err != nil {
+		return nil, err
+	}
+	return &socksTransportFactory{dialer}, nil
+}
+
+type socksTransportFactory struct {
+	dialer proxy.Dialer
+}
+
+func (f *socksTransportFactory) GetTransport(trans thrift.TTransport) thrift.TTransport {
+	// If this is a SOCKS-able connection, then return a TTransport that uses SOCKS.
+	// If it's not, return trans unmodified.
+	tsock, ok := trans.(*thrift.TSocket)
+	if !ok {
+		// Don't know how to wrap anything other than a TSocket
+		return trans
+	}
+	if tsock.IsOpen() {
+		// Transport Factory should be called before Open
+		return trans
+	}
+	addr, ok := tsock.Addr().(*net.TCPAddr)
+	if !ok {
+		return trans
+	}
+	ip := addr.IP.To4()
+	if ip == nil {
+		return trans
+	}
+
+	// An Address is Socks-able if it starts with 10, because Twitter's production network lives in
+	// 10/8 in IPv4 space.
+	if ip[0] != 10 {
+		return trans
+	}
+
+	if f.dialer == nil {
+		// We want to use SOCKS, but can't, because we have no dialer
+		log.Info("transport will not use SOCKS proxy because SOCKS_PORT is unset", addr.String())
+		return trans
+	}
+
+	return &socksSocket{
+		addr:    addr.String(),
+		timeout: 0, // thrift.TSocket gives us no way to extract the timeout
+		dialer:  f.dialer,
+	}
+}
+
+// socksSocket creates a socket via the proxy dialer.
+// (Ideally, there would be a form of TSocket that took a Dialer instead of a net.Conn)
+type socksSocket struct {
+	*thrift.TSocket
+	addr    string
+	timeout time.Duration
+	dialer  proxy.Dialer
+}
+
+func (s *socksSocket) Open() error {
+	if s.IsOpen() {
+		return s.Open()
+	}
+	conn, err := s.dialer.Dial("tcp", s.addr)
+	if err != nil {
+		log.Infof("Failed connecting to %s via proxy, trying directly\n", s.addr)
+		conn, err = net.DialTimeout("tcp", s.addr, time.Duration(10*time.Second))
+		if err != nil {
+			return err
+		}
+	}
+
+	s.TSocket = thrift.NewTSocketFromConnTimeout(conn, 0)
+	return nil
+}
+
+func GetCluster(clusterJSON config.ClusterJSONConfig) (*cluster.Cluster, error) {
+	var cluster *cluster.Cluster
+	var err error
+	if clusterJSON.Type == "inMemory" {
+		cmc := &config.ClusterMemoryConfig{
+			Count: clusterJSON.Count,
+		}
+		cluster, err = cmc.Create()
+	} else {
+		clc := &config.ClusterLocalConfig{}
+		cluster, err = clc.Create()
+	}
+	if err != nil {
+		return nil, fmt.Errorf("error creating cluster.  Scheduler not started. %s", err)
+	}
+
+	return cluster, nil
+}
+
+// MakeSagaLog - TODO remove saga or refactor it so this function can be moved into saga or sagalog
+// the current organization leads to cyclic dependency when moving to saga or sagalogs
+func MakeSagaLog(config config.SagaLogJSONConfig) (saga.SagaLog, error) {
+	if config.Type == "memory" {
+		return sagalogs.MakeInMemorySagaLog(time.Duration(config.ExpirationSec)*time.Second, time.Duration(config.GCIntervalSec)*time.Second), nil
+	}
+	if config.Type == "file" {
+		return sagalogs.MakeFileSagaLog(config.Directory)
+	}
+
+	return nil, fmt.Errorf("unsupported sagalog type: %s.  No sagalog created", config.Type)
+}
diff --git a/scheduler/starter/start_server.go b/scheduler/starter/start_server.go
new file mode 100644
index 000000000..6ccd4d2ef
--- /dev/null
+++ b/scheduler/starter/start_server.go
@@ -0,0 +1,87 @@
+package starter
+
+import (
+	"fmt"
+	"time"
+
+	"github.com/apache/thrift/lib/go/thrift"
+	log "github.com/sirupsen/logrus"
+
+	"github.com/twitter/scoot/bazel"
+	"github.com/twitter/scoot/bazel/execution"
+	"github.com/twitter/scoot/cloud/cluster"
+	"github.com/twitter/scoot/common/endpoints"
+	"github.com/twitter/scoot/common/stats"
+	"github.com/twitter/scoot/runner"
+	"github.com/twitter/scoot/saga"
+	"github.com/twitter/scoot/scheduler/api"
+	"github.com/twitter/scoot/scheduler/scheduler/config"
+	"github.com/twitter/scoot/scheduler/server"
+	"github.com/twitter/scoot/workerapi/client"
+)
+
+type servers struct {
+	thrift thrift.TServer
+	http   *endpoints.TwitterServer
+	grpc   bazel.GRPCServer
+}
+
+func makeServers(
+	thrift thrift.TServer,
+	http *endpoints.TwitterServer,
+	grpc bazel.GRPCServer) servers {
+	return servers{thrift, http, grpc}
+}
+
+// StartServer construct and start scheduler service (without using ice)
+func StartServer(schedulerConfig server.SchedulerConfiguration,
+	sagaLogConfig config.SagaLogJSONConfig,
+	workers client.WorkersClientJSONConfig,
+	thriftServerTransport thrift.TServerTransport,
+	statsReceiver *stats.StatsReceiver,
+	workerClientTimeout time.Duration,
+	endpoints *endpoints.TwitterServer,
+	bazelGRPCConfig *bazel.GRPCConfig,
+	persistor server.Persistor,
+	durationKeyExtractorFn func(string) string,
+	clusterIn *cluster.Cluster) error {
+
+	thriftTransportFactory := thrift.NewTTransportFactory()
+
+	binaryProtocolFactory := thrift.NewTBinaryProtocolFactoryDefault()
+
+	var err error
+	var sl saga.SagaLog
+	if sl, err = MakeSagaLog(sagaLogConfig); err != nil {
+		return err
+	}
+	sagaCoordinator := saga.MakeSagaCoordinator(sl)
+
+	var rf func(cluster.Node) runner.Service
+	if rf, err = GetWorkerRunnerServiceFn(workers, thriftTransportFactory, binaryProtocolFactory); err != nil {
+		return fmt.Errorf("%s.  Scheduler not started", err)
+	}
+
+	statefulScheduler := server.NewStatefulSchedulerFromCluster(clusterIn, sagaCoordinator, rf, schedulerConfig, *statsReceiver, persistor, durationKeyExtractorFn)
+
+	bazelServer := execution.MakeExecutionServer(bazelGRPCConfig, statefulScheduler, *statsReceiver)
+
+	thriftHandler := api.NewHandler(statefulScheduler, sagaCoordinator, *statsReceiver)
+	thriftServer := api.MakeServer(thriftHandler, thriftServerTransport, thriftTransportFactory, binaryProtocolFactory)
+
+	servers := makeServers(thriftServer, endpoints, bazelServer)
+
+	errCh := make(chan error)
+	go func() {
+		errCh <- servers.http.Serve()
+	}()
+	go func() {
+		errCh <- servers.thrift.Serve()
+	}()
+	go func() {
+		errCh <- servers.grpc.Serve()
+	}()
+	log.Fatal("Error serving: ", <-errCh)
+
+	return nil
+}
diff --git a/workerapi/client/client.go b/workerapi/client/client.go
index a051de6f6..425cfc3a4 100644
--- a/workerapi/client/client.go
+++ b/workerapi/client/client.go
@@ -13,6 +13,12 @@ import (
 	"github.com/twitter/scoot/workerapi/gen-go/worker"
 )
 
+// Parameters for configuring connections to remote workers.
+type WorkersClientJSONConfig struct {
+	Type          string // transport type: rpc
+	PollingPeriod string // polling period default to 250ms
+}
+
 type Client interface {
 	// Connection funtions
 	Dial() error
diff --git a/workerapi/client/thrift_client.go b/workerapi/client/thrift_client.go
new file mode 100644
index 000000000..70f932fd3
--- /dev/null
+++ b/workerapi/client/thrift_client.go
@@ -0,0 +1,40 @@
+package client
+
+import (
+	"time"
+
+	"github.com/apache/thrift/lib/go/thrift"
+
+	"github.com/twitter/scoot/cloud/cluster"
+	"github.com/twitter/scoot/common/dialer"
+	"github.com/twitter/scoot/runner"
+	"github.com/twitter/scoot/runner/runners"
+)
+
+const defaultPollingPeriod = time.Duration(250) * time.Millisecond
+
+func NewWorkerThriftClient(
+	tf thrift.TTransportFactory,
+	pf thrift.TProtocolFactory,
+	ct time.Duration,
+	wc WorkersClientJSONConfig) (func(cluster.Node) runner.Service, error) {
+
+	pollingPeriod := defaultPollingPeriod
+	var err error
+
+	// apply defaults
+	if wc.PollingPeriod != "" {
+		pollingPeriod, err = time.ParseDuration(wc.PollingPeriod)
+		if err != nil {
+			return nil, err
+		}
+	}
+
+	rf := func(node cluster.Node) runner.Service {
+		di := dialer.NewSimpleDialer(tf, pf, time.Duration(ct))
+		cl, _ := NewSimpleClient(di, string(node.Id()))
+		return runners.NewPollingService(cl, cl, pollingPeriod)
+	}
+
+	return rf, nil
+}


Test patch:
diff --git a/perftests/scheduler_simulator/test_alg.go b/perftests/scheduler_simulator/test_alg.go
index cec1d8921..1ac9ec006 100644
--- a/perftests/scheduler_simulator/test_alg.go
+++ b/perftests/scheduler_simulator/test_alg.go
@@ -427,8 +427,8 @@ func (st *SchedulingAlgTester) makeTestCluster(num int) *testCluster {
 	return h
 }
 
-func (st *SchedulingAlgTester) getTestConfig() server.SchedulerConfig {
-	return server.SchedulerConfig{
+func (st *SchedulingAlgTester) getTestConfig() server.SchedulerConfiguration {
+	return server.SchedulerConfiguration{
 		MaxRetriesPerTask:    0,
 		DebugMode:            false,
 		RecoverJobsOnStartup: false,
diff --git a/scheduler/scheduler/config/config_test.go b/scheduler/scheduler/config/config_test.go
new file mode 100644
index 000000000..88973959d
--- /dev/null
+++ b/scheduler/scheduler/config/config_test.go
@@ -0,0 +1,37 @@
+package config
+
+import (
+	"fmt"
+	"testing"
+
+	"github.com/stretchr/testify/assert"
+)
+
+var tests = []string{"local.memory", "local.local"}
+
+// Tests to ensure config is properly specified
+// and that they parse correctly
+func TestGettingConfigurations(t *testing.T) {
+	for _, configSelector := range tests {
+		_, err := GetSchedulerConfigs(configSelector)
+		assert.Nil(t, err, fmt.Sprintf("error getting schedule server config.  %s", err))
+	}
+
+	selector := "invalid.selector"
+	config, err := GetSchedulerConfigs(selector)
+	assert.NotNil(t, err, fmt.Sprintf("configuration returned for %s: %s", selector, config))
+}
+
+// TestCreatingConfigStruct test overriding default structure values with values from
+// command line's specification.
+func TestCreatingConfigStruct(t *testing.T) {
+	jsonConfig, err := GetSchedulerConfigs("local.local")
+	assert.Nil(t, err)
+	assert.Equal(t, "local", jsonConfig.Cluster.Type)
+	assert.Equal(t, "file", jsonConfig.SagaLog.Type)
+	assert.Equal(t, ".scootdata/filesagalog", jsonConfig.SagaLog.Directory)
+
+	config, err := jsonConfig.Scheduler.CreateSchedulerConfig()
+	assert.Nil(t, err)
+	assert.True(t, config.RecoverJobsOnStartup)
+}
diff --git a/scheduler/scheduler/main_test.go b/scheduler/scheduler/main_test.go
deleted file mode 100644
index 6fa75cf6a..000000000
--- a/scheduler/scheduler/main_test.go
+++ /dev/null
@@ -1,29 +0,0 @@
-package main
-
-import (
-	"fmt"
-	"github.com/twitter/scoot/scheduler/api"
-	"github.com/twitter/scoot/scheduler/scheduler/config"
-	"testing"
-)
-
-var tests = []string{"local.memory", "local.local"}
-
-// Tests to ensure config is properly specified
-// and that they parse correctly
-func TestConfigParses(t *testing.T) {
-	_, schema := api.Defaults()
-
-	for _, configFile := range tests {
-		config, err := config.Asset(fmt.Sprintf("config/%v", configFile))
-
-		if err != nil {
-			t.Errorf("Error Getting Config File: %v", configFile)
-		}
-
-		_, err = schema.Parse(config)
-		if err != nil {
-			t.Errorf("Error Parsing Config File %v, with Error %v", configFile, err)
-		}
-	}
-}
diff --git a/scheduler/server/stateful_scheduler_test.go b/scheduler/server/stateful_scheduler_test.go
index f79147e2c..8ff6d733a 100644
--- a/scheduler/server/stateful_scheduler_test.go
+++ b/scheduler/server/stateful_scheduler_test.go
@@ -43,7 +43,7 @@ type schedulerDeps struct {
 	clUpdates       chan []cluster.NodeUpdate
 	sc              saga.SagaCoordinator
 	rf              func(cluster.Node) runner.Service
-	config          SchedulerConfig
+	config          SchedulerConfiguration
 	nodeToWorkerMap map[string]runner.Service
 	statsRegistry   stats.StatsRegistry
 }
@@ -60,7 +60,7 @@ func getDefaultSchedDeps() *schedulerDeps {
 		rf: func(n cluster.Node) runner.Service {
 			return worker.MakeInmemoryWorker(n)
 		},
-		config: SchedulerConfig{
+		config: SchedulerConfiguration{
 			MaxRetriesPerTask:    0,
 			DebugMode:            true,
 			RecoverJobsOnStartup: false,
@@ -773,7 +773,7 @@ func getDepsWithSimWorker() (*schedulerDeps, []*execers.SimExecer) {
 			runner := runners.NewSingleRunner(ex, filerMap, runners.NewNullOutputCreator(), nil, stats.NopDirsMonitor, runner.EmptyID)
 			return runner
 		},
-		config: SchedulerConfig{
+		config: SchedulerConfiguration{
 			MaxRetriesPerTask:    0,
 			DebugMode:            true,
 			RecoverJobsOnStartup: false,
diff --git a/scheduler/server/task_scheduler_test.go b/scheduler/server/task_scheduler_test.go
index 2ded21d55..2ad5aff14 100644
--- a/scheduler/server/task_scheduler_test.go
+++ b/scheduler/server/task_scheduler_test.go
@@ -141,7 +141,7 @@ func getDebugStatefulScheduler(tc *testCluster) *statefulScheduler {
 	rf := func(n cluster.Node) runner.Service {
 		return worker.MakeInmemoryWorker(n)
 	}
-	sc := SchedulerConfig{
+	sc := SchedulerConfiguration{
 		MaxRetriesPerTask:    0,
 		DebugMode:            true,
 		RecoverJobsOnStartup: false,