<commit_before>/*
Master package is the main package that keeps everything running as it should be. It's responsible for starting, stopping and deleting processes. It also will keep an eye on the Watcher in case a process dies so it can restart it again.

RemoteMaster is responsible for exporting the main APM operations as HTTP requests. If you want to start a Remote Server, run:

- remoteServer := master.StartRemoteMasterServer(dsn, configFile)

It will start a remote master and return the instance.

To make remote requests, use the Remote Client by instantiating using:

- remoteClient, err := master.StartRemoteClient(dsn, timeout)

It will start the remote client and return the instance so you can use to initiate requests, such as:

- remoteClient.StartGoBin(sourcePath, name, keepAlive, args)
*/

package master

import "os"
import "path"
import "errors"
import "fmt"
import "sync"

import "time"

import "github.com/topfreegames/apm/lib/preparable"
import "github.com/topfreegames/apm/lib/process"
import "github.com/topfreegames/apm/lib/utils"
import "github.com/topfreegames/apm/lib/watcher"

import log "github.com/Sirupsen/logrus"

// Master is the main module that keeps everything in place and execute
// the necessary actions to keep the process running as they should be.
type Master struct {
	sync.Mutex

	SysFolder string           // SysFolder is the main APM folder where the necessary config files will be stored.
	PidFile   string           // PidFille is the APM pid file path.
	OutFile   string           // OutFile is the APM output log file path.
	ErrFile   string           // ErrFile is the APM err log file path.
	Watcher   *watcher.Watcher // Watcher is a watcher instance.

	Procs map[string]process.ProcContainer // Procs is a map containing all procs started on APM.
}

type DecodableMaster struct {
	SysFolder string
	PidFile string
	OutFile string
	ErrFile string

	Watcher *watcher.Watcher

	Procs map[string]*process.Proc
}

// InitMaster will start a master instance with configFile.
// It returns a Master instance.
func InitMaster(configFile string) *Master {
	watcher := watcher.InitWatcher()
	decodableMaster := &DecodableMaster{}
	decodableMaster.Procs = make(map[string]*process.Proc)

	err := utils.SafeReadTomlFile(configFile, decodableMaster)
	if err != nil {
		panic(err)
	}

	procs := make(map[string]process.ProcContainer)
	for k, v := range decodableMaster.Procs {
		procs[k] = v;
	}
	// We need this hack because toml decoder doesn't decode to interfaces
	master := &Master {<commit_msg>Adding comment explaining DecodableMaster struct<commit_after>/*
Master package is the main package that keeps everything running as it should be. It's responsible for starting, stopping and deleting processes. It also will keep an eye on the Watcher in case a process dies so it can restart it again.

RemoteMaster is responsible for exporting the main APM operations as HTTP requests. If you want to start a Remote Server, run:

- remoteServer := master.StartRemoteMasterServer(dsn, configFile)

It will start a remote master and return the instance.

To make remote requests, use the Remote Client by instantiating using:

- remoteClient, err := master.StartRemoteClient(dsn, timeout)

It will start the remote client and return the instance so you can use to initiate requests, such as:

- remoteClient.StartGoBin(sourcePath, name, keepAlive, args)
*/

package master

import "os"
import "path"
import "errors"
import "fmt"
import "sync"

import "time"

import "github.com/topfreegames/apm/lib/preparable"
import "github.com/topfreegames/apm/lib/process"
import "github.com/topfreegames/apm/lib/utils"
import "github.com/topfreegames/apm/lib/watcher"

import log "github.com/Sirupsen/logrus"

// Master is the main module that keeps everything in place and execute
// the necessary actions to keep the process running as they should be.
type Master struct {
	sync.Mutex

	SysFolder string           // SysFolder is the main APM folder where the necessary config files will be stored.
	PidFile   string           // PidFille is the APM pid file path.
	OutFile   string           // OutFile is the APM output log file path.
	ErrFile   string           // ErrFile is the APM err log file path.
	Watcher   *watcher.Watcher // Watcher is a watcher instance.

	Procs map[string]process.ProcContainer // Procs is a map containing all procs started on APM.
}

// DecodableMaster is a struct that the config toml file will decode to.
// It is needed because toml decoder doesn't decode to interfaces, so the
// Procs map can't be decoded as long as we use the ProcContainer interface
type DecodableMaster struct {
	SysFolder string
	PidFile string
	OutFile string
	ErrFile string

	Watcher *watcher.Watcher

	Procs map[string]*process.Proc
}

// InitMaster will start a master instance with configFile.
// It returns a Master instance.
func InitMaster(configFile string) *Master {
	watcher := watcher.InitWatcher()
	decodableMaster := &DecodableMaster{}
	decodableMaster.Procs = make(map[string]*process.Proc)

	err := utils.SafeReadTomlFile(configFile, decodableMaster)
	if err != nil {
		panic(err)
	}

	procs := make(map[string]process.ProcContainer)
	for k, v := range decodableMaster.Procs {
		procs[k] = v;
	}
	// We need this hack because toml decoder doesn't decode to interfaces
	master := &Master {
{'fraction_non_alphanumeric': 0.07292445774121167, 'fraction_numerical': 0.0, 'mean_word_length': 3.999065420560748, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7516975', 'n_tokens_mistral': 1581, 'n_tokens_neox': 1535, 'n_words': 639}