Loader.go

package core

import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"net/http"
	"os"
	"path/filepath"
	"regexp"
	"strings"

	"your_project/util"
)

// Config constants
const (
	LOADER = "loader.json"
	SOURCE = "source"
	DS     = string(os.PathSeparator)
)

// Loader ๊ตฌ์กฐ์ฒด ์ •์˜
type Loader struct{}

// Ref ๋ฉ”์„œ๋“œ๋Š” loader.json ํŒŒ์ผ์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ์ฝ์–ด์™€ map[string]interface{} ํ˜•ํƒœ๋กœ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.
func (l *Loader) Ref() map[string]interface{} {
	ref := make(map[string]interface{})
	data, err := ioutil.ReadFile(LOADER)
	if err != nil {
		return nil
	}
	json.Unmarshal(data, &ref)
	return ref
}

// Build ๋ฉ”์„œ๋“œ๋Š” ์ฃผ์–ด์ง„ ์˜ต์…˜์— ๋”ฐ๋ผ loader.json ํŒŒ์ผ์„ ์—…๋ฐ์ดํŠธํ•ฉ๋‹ˆ๋‹ค.
func (l *Loader) Build(options map[string]string) {
	ref := l.Ref()
	apiRoot := options["api_root"]
	scriptRoot := options["script_root"]
	serviceRoot := options["service_root"]

	ref["api"] = l.Items(apiRoot)
	ref["script"] = l.Items(scriptRoot)
	ref["service"] = l.Items(serviceRoot)

	data, _ := json.Marshal(ref)
	ioutil.WriteFile(LOADER, data, 0644)
}

// Items ๋ฉ”์„œ๋“œ๋Š” ์ฃผ์–ด์ง„ ๋””๋ ‰ํ† ๋ฆฌ ๋‚ด์˜ ํŒŒ์ผ ๋ชฉ๋ก์„ ์ฝ์–ด์™€ map[string]string ํ˜•ํƒœ๋กœ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.
func (l *Loader) Items(directory string) map[string]string {
	items := make(map[string]string)
	if _, err := os.Stat(directory); os.IsNotExist(err) {
		return items
	}

	files, _ := util.ListFiles(directory)
	for _, file := range files {
		class := strings.TrimSuffix(strings.TrimPrefix(file, SOURCE+DS), ".go")
		name := strings.TrimSuffix(strings.TrimPrefix(file, directory+DS), ".go")
		name = util.ToLower(strings.ReplaceAll(name, DS, "/"))
		items[name] = strings.ReplaceAll(class, DS, ".")
	}
	return items
}

// API ๋ฉ”์„œ๋“œ๋Š” HTTP ์š”์ฒญ์„ ์ฒ˜๋ฆฌํ•˜๊ณ  ํ•ด๋‹นํ•˜๋Š” API๋ฅผ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค.
func (l *Loader) API() {
	// ์ž…๋ ฅ ์ฒ˜๋ฆฌ
	rawParameters, _ := ioutil.ReadAll(os.Stdin)
	var rawParams map[string]interface{}
	json.Unmarshal(rawParameters, &rawParams)
	for k, v := range rawParams {
		os.Setenv(k, fmt.Sprint(v))
	}

	// ๊ฒฝ๋กœ ํŒŒ์‹ฑ
	uri := os.Getenv("REQUEST_URI")
	apiName := util.ToLower(strings.Trim(uri, "/"))
	if apiName == "" {
		apiName = "main"
	}

	// ์‹คํ–‰
	ref := l.Ref()
	class, found := ref["api"].(map[string]interface{})[apiName]
	if !found {
		api := Api{}
		api.Fail(http.StatusNotFound, "Api not found. Please check request uri.")
	} else {
		// class์˜ main ํ•จ์ˆ˜ ํ˜ธ์ถœ ๋กœ์ง ์ถ”๊ฐ€
	}
}

// ExecApi ๋ฉ”์„œ๋“œ๋Š” ์ฃผ์–ด์ง„ Api ๊ตฌ์กฐ์ฒด์˜ Main ํ•จ์ˆ˜๋ฅผ ์‹คํ–‰ํ•˜๊ณ  ๊ฒฐ๊ณผ๋ฅผ ์ฒ˜๋ฆฌํ•ฉ๋‹ˆ๋‹ค.
func (l *Loader) ExecApi(api Api) {
	// ์‹คํ–‰
	r := api.Main()

	// ํด๋ž˜์Šค๋ฅผ ๋ฐฐ์—ด๋กœ ๋ณ€ํ™˜
	if _, ok := r.(map[string]interface{}); !ok {
		r = util.ObjectToMap(r)
	}

	// ๊ฒฐ๊ณผ ์ƒ์„ฑ
	if _, ok := r.(Result); !ok {
		result := Result{}
		result.Data = r
		r = result
	}

	if res, ok := r.(Result); ok {
		res.Code = http.StatusOK
		api.View(res)
	}
}

// Script ๋ฉ”์„œ๋“œ๋Š” ์ฃผ์–ด์ง„ ์ธ์ž์— ๋”ฐ๋ผ ์Šคํฌ๋ฆฝํŠธ๋ฅผ ์‹คํ–‰ํ•˜๊ฑฐ๋‚˜ ๋„์›€๋ง์„ ์ถœ๋ ฅํ•ฉ๋‹ˆ๋‹ค.
func (l *Loader) Script(argv []string) {
	scriptName := util.ToLower(strings.Trim(argv[1], "/"))

	// ๋ฒ„์ „ ํ™•์ธ
	if scriptName == "--version" || scriptName == "-v" {
		scriptName = "version"
	}

	// ์‹คํ–‰
	ref := l.Ref()
	class, found := ref["script"].(map[string]interface{})[scriptName]
	if !found {
		class = ref["script"].(map[string]interface{})["help"]
	}

	if class != nil {
		// script์˜ main ํ•จ์ˆ˜ ํ˜ธ์ถœ ๋กœ์ง ์ถ”๊ฐ€
		inputs := l.ReadArg(argv)
		l.ExecScript(script, inputs)
	} else {
		l.DefaultScript(scriptName)
	}
}

// DefaultScript ๋ฉ”์„œ๋“œ๋Š” ์ฃผ์–ด์ง„ ์Šคํฌ๋ฆฝํŠธ๋ช…์— ๋”ฐ๋ฅธ ๊ธฐ๋ณธ ๋„์›€๋ง์„ ์ถœ๋ ฅํ•ฉ๋‹ˆ๋‹ค.
func (l *Loader) DefaultScript(scriptName string) {
	var str strings.Builder
	ref := l.Ref()
	items := ref["script"].(map[string]interface{})
	base := filepath.Base(os.Args[0])
	var outputs []string
	maxlength := 0

	str.WriteString("\nUsage: " + base + " <command> \n\nCommands: \n")

	for key := range items {
		if strings.HasPrefix(key, scriptName) {
			outputs = append(outputs, key)
			if len(key) > maxlength {
				maxlength = len(key)
			}
		}
	}

	if len(outputs) == 0 {
		for key := range items {
			outputs = append(outputs, key)
			if len(key) > maxlength {
				maxlength = len(key)
			}
		}
	}

	for _, key := range outputs {
		class := ref["script"].(map[string]interface{})[key]
		description := "" // class์˜ ์„ค๋ช… ์ถ”๊ฐ€
		str.WriteString("  " + key + strings.Repeat(" ", maxlength-len(key)+1) + description + "\n")
	}

	fmt.Println(str.String())
}

// ReadArg ๋ฉ”์„œ๋“œ๋Š” ์ฃผ์–ด์ง„ ์ธ์ž ๋ฐฐ์—ด์„ ํŒŒ์‹ฑํ•˜์—ฌ map[string]string์œผ๋กœ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.
func (l *Loader) ReadArg(argv []string) map[string]string {
	inputs := make(map[string]string)

	for i := 2; i < len(argv); i++ {
		arg := argv[i]

		if match, _ := regexp.MatchString(`^-([a-zA-Z_])$`, arg); match {
			inputs[arg[1:2]] = argv[i+1]
			i++
		} else if match, _ := regexp.MatchString(`^-([a-zA-Z_])(.+)`, arg); match {
			inputs[arg[1:2]] = arg[2:]
		} else if match, _ := regexp.MatchString(`^--([a-zA-Z0-9_]+)$`, arg); match {
			inputs[arg[2:]] = argv[i+1]
			i++
		} else if match, _ := regexp.MatchString(`^--([a-zA-Z0-9_]+)=(.+)`, arg); match {
			inputs[arg[2:strings.Index(arg, "=")]] = arg[strings.Index(arg, "=")+1:]
		} else {
			inputs[arg] = ""
		}
	}

	return inputs
}

// ExecScript ๋ฉ”์„œ๋“œ๋Š” ์ฃผ์–ด์ง„ Script ๊ตฌ์กฐ์ฒด์˜ Args์™€ Main ํ•จ์ˆ˜๋ฅผ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค.
func (l *Loader) ExecScript(script Script, inputs map[string]string) {
	// ์‹คํ–‰
	script.Args(inputs)
	script.Main()
}

// Service ๋ฉ”์„œ๋“œ๋Š” ์ฃผ์–ด์ง„ ์„œ๋น„์Šค๋ช…์— ๋”ฐ๋ผ ํ•ด๋‹น ์„œ๋น„์Šค๋ฅผ ์‹คํ–‰ํ•˜๊ฑฐ๋‚˜ ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ ์„œ๋น„์Šค ๋ชฉ๋ก์„ ์ถœ๋ ฅํ•ฉ๋‹ˆ๋‹ค.
func (l *Loader) Service(serviceBin string, argv []string) {
	// ์ดˆ๊ธฐํ™”
	serviceName := util.ToLower(strings.Trim(argv[1], "/"))
	inputs := argv[2:]

	// ์‹คํ–‰
	if serviceName == "run" {
		fmt.Println("runService: ", strings.Join(inputs, " "))
		l.RunService(serviceBin, inputs)
		return
	}

	// ์‹คํ–‰
	ref := l.Ref()
	class, found := ref["service"].(map[string]interface{})[serviceName]
	if !found {
		fmt.Println("\nService not found. Please check service name. \n\n[Available services]\n")
		for key := range ref["service"].(map[string]interface{}) {
			fmt.Println(" - " + key)
		}
		fmt.Println()
	} else {
		// class์˜ main ํ•จ์ˆ˜ ํ˜ธ์ถœ ๋กœ์ง ์ถ”๊ฐ€
		l.ExecService(service, inputs)
	}
}

// RunService ๋ฉ”์„œ๋“œ๋Š” ์ฃผ์–ด์ง„ ์„œ๋น„์Šค๋ช…๊ณผ ์ž…๋ ฅ์— ๋”ฐ๋ผ ํ•ด๋‹น ์„œ๋น„์Šค๋ฅผ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค.
func (l *Loader) RunService(serviceBin string, inputs []string) {
	serviceName := util.ToLower(strings.Trim(inputs[0], "/"))
	inputs = inputs[1:]

	if serviceName == "run" {
		os.Exit(0)
	}

	util.ForkProcess(serviceBin, serviceName, inputs)
}

// ExecService ๋ฉ”์„œ๋“œ๋Š” ์ฃผ์–ด์ง„ Service ๊ตฌ์กฐ์ฒด์˜ Args, Init, Main ๋ฐ Iterate ํ•จ์ˆ˜๋ฅผ ๋ฐ˜๋ณต ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค.
func (l *Loader) ExecService(service Service, inputs []string) {
	// ๊ฐ€๋น„์ง€ ์ปฌ๋ ‰ํ„ฐ
	if os.Getenv("ENABLE_GC") == "true" {
		util.EnableGC()
	}

	// ์‹คํ–‰
	service.Args(inputs)
	service.Init()

	for {
		service.Main()
		service.Iterate()

		util.ClearStatCache()

		if os.Getenv("ENABLE_GC") == "true" {
			util.CollectCycles()
		}
	}
}

1. Ref ๋ฉ”์„œ๋“œ

  • ์—ญํ• : LOADER ํŒŒ์ผ(๋ณดํ†ต loader.json)์„ ์ฝ์–ด์„œ JSON ๋ฐ์ดํ„ฐ๋ฅผ ๋งต ํ˜•ํƒœ๋กœ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

  • ๋™์ž‘ ๋ฐฉ์‹:

    • ioutil.ReadFile(LOADER)๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํŒŒ์ผ์„ ์ฝ์Šต๋‹ˆ๋‹ค. ํŒŒ์ผ์ด ์—†๊ฑฐ๋‚˜ ์ฝ๊ธฐ์— ์‹คํŒจํ•˜๋ฉด nil์„ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

    • ํŒŒ์ผ์˜ ๋‚ด์šฉ์„ json.Unmarshal์„ ์‚ฌ์šฉํ•˜์—ฌ ref ๋งต์— ์–ธ๋งˆ์ƒฌ๋ง(๋””์ฝ”๋”ฉ)ํ•ฉ๋‹ˆ๋‹ค.

    • ์–ธ๋งˆ์ƒฌ๋ง๋œ ref ๋งต์„ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

2. Build ๋ฉ”์„œ๋“œ

  • ์—ญํ• : ์ง€์ •๋œ ๋””๋ ‰ํ† ๋ฆฌ์—์„œ API, ์Šคํฌ๋ฆฝํŠธ, ์„œ๋น„์Šค ํ•ญ๋ชฉ์„ ์Šค์บ”ํ•˜์—ฌ LOADER ํŒŒ์ผ์„ ์—…๋ฐ์ดํŠธํ•ฉ๋‹ˆ๋‹ค.

  • ๋™์ž‘ ๋ฐฉ์‹:

    • Ref ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ ๊ธฐ์กด์˜ loader.json ํŒŒ์ผ ๋‚ด์šฉ์„ ์ฝ์–ด์˜ต๋‹ˆ๋‹ค.

    • ์˜ต์…˜์œผ๋กœ ๋ฐ›์€ api_root, script_root, service_root ๋””๋ ‰ํ† ๋ฆฌ๋ฅผ ๊ฐ๊ฐ Items ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์Šค์บ”ํ•ฉ๋‹ˆ๋‹ค.

    • ๊ฐ ๋””๋ ‰ํ† ๋ฆฌ์˜ ๋‚ด์šฉ์„ ref ๋งต์— ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค.

    • json.Marshal์„ ์‚ฌ์šฉํ•˜์—ฌ ref ๋งต์„ JSON์œผ๋กœ ๋ณ€ํ™˜ํ•˜๊ณ , ioutil.WriteFile์„ ์‚ฌ์šฉํ•˜์—ฌ LOADER ํŒŒ์ผ์— ์”๋‹ˆ๋‹ค.

3. Items ๋ฉ”์„œ๋“œ

  • ์—ญํ• : ์ง€์ •๋œ ๋””๋ ‰ํ† ๋ฆฌ ๋‚ด์˜ ํŒŒ์ผ๋“ค์„ ์Šค์บ”ํ•˜์—ฌ ํŒŒ์ผ ๊ฒฝ๋กœ์™€ ํด๋ž˜์Šค ์ด๋ฆ„์„ ๋งต ํ˜•ํƒœ๋กœ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

  • ๋™์ž‘ ๋ฐฉ์‹:

    • os.Stat๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋””๋ ‰ํ† ๋ฆฌ์˜ ์กด์žฌ ์—ฌ๋ถ€๋ฅผ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค. ๋””๋ ‰ํ† ๋ฆฌ๊ฐ€ ์—†์œผ๋ฉด ๋นˆ ๋งต์„ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

    • util.ListFiles(directory)๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋””๋ ‰ํ† ๋ฆฌ ๋‚ด ๋ชจ๋“  ํŒŒ์ผ์„ ๋ฆฌ์ŠคํŠธ๋กœ ๊ฐ€์ ธ์˜ต๋‹ˆ๋‹ค.

    • ๊ฐ ํŒŒ์ผ์— ๋Œ€ํ•ด:

      • SOURCE+DS ๋ฐ .go ํ™•์žฅ์ž๋ฅผ ์ œ๊ฑฐํ•˜์—ฌ ํด๋ž˜์Šค ์ด๋ฆ„์„ ์ถ”์ถœํ•ฉ๋‹ˆ๋‹ค.

      • ๋””๋ ‰ํ† ๋ฆฌ ๊ฒฝ๋กœ์™€ .go ํ™•์žฅ์ž๋ฅผ ์ œ๊ฑฐํ•˜๊ณ , ๊ฒฝ๋กœ ๊ตฌ๋ถ„์ž๋ฅผ /๋กœ ๋ฐ”๊พธ๊ณ  ์†Œ๋ฌธ์ž๋กœ ๋ณ€ํ™˜ํ•˜์—ฌ ์ด๋ฆ„์„ ์ถ”์ถœํ•ฉ๋‹ˆ๋‹ค.

      • ํด๋ž˜์Šค ์ด๋ฆ„์„ .์œผ๋กœ ๊ตฌ๋ถ„ํ•˜์—ฌ ์ €์žฅํ•ฉ๋‹ˆ๋‹ค.

    • ์™„์„ฑ๋œ items ๋งต์„ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

4. API ๋ฉ”์„œ๋“œ

  • ์—ญํ• : API ์š”์ฒญ์„ ์ฒ˜๋ฆฌํ•ฉ๋‹ˆ๋‹ค.

  • ๋™์ž‘ ๋ฐฉ์‹:

    • os.Stdin์—์„œ ์ž…๋ ฅ์„ ์ฝ์–ด์™€ rawParams ๋งต์œผ๋กœ ์–ธ๋งˆ์ƒฌ๋งํ•ฉ๋‹ˆ๋‹ค.

    • ๊ฐ ์ž…๋ ฅ ํŒŒ๋ผ๋ฏธํ„ฐ๋ฅผ ํ™˜๊ฒฝ ๋ณ€์ˆ˜๋กœ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค.

    • REQUEST_URI ํ™˜๊ฒฝ ๋ณ€์ˆ˜์—์„œ ์š”์ฒญ๋œ URI๋ฅผ ๊ฐ€์ ธ์™€ API ์ด๋ฆ„์„ ์ถ”์ถœํ•ฉ๋‹ˆ๋‹ค. ๊ธฐ๋ณธ๊ฐ’์€ main์ž…๋‹ˆ๋‹ค.

    • Ref ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ API ๋งต์„ ๊ฐ€์ ธ์˜ต๋‹ˆ๋‹ค. ์š”์ฒญ๋œ API๊ฐ€ ์กด์žฌํ•˜์ง€ ์•Š์œผ๋ฉด 404 ์˜ค๋ฅ˜๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

    • ์กด์žฌํ•˜๋ฉด ํ•ด๋‹น API ํด๋ž˜์Šค๋ฅผ ์ฐพ์•„์„œ main ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ๋กœ์ง์„ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค.

5. ExecApi ๋ฉ”์„œ๋“œ

  • ์—ญํ• : API๋ฅผ ์‹คํ–‰ํ•˜๊ณ  ๊ฒฐ๊ณผ๋ฅผ ์ฒ˜๋ฆฌํ•ฉ๋‹ˆ๋‹ค.

  • ๋™์ž‘ ๋ฐฉ์‹:

    • api.Main()์„ ํ˜ธ์ถœํ•˜์—ฌ ๊ฒฐ๊ณผ๋ฅผ ๋ฐ›์Šต๋‹ˆ๋‹ค.

    • ๊ฒฐ๊ณผ๊ฐ€ map[string]interface{} ํƒ€์ž…์ด ์•„๋‹ˆ๋ฉด util.ObjectToMap์„ ์‚ฌ์šฉํ•˜์—ฌ ๋ณ€ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

    • ๊ฒฐ๊ณผ๊ฐ€ Result ํƒ€์ž…์ด ์•„๋‹ˆ๋ฉด Result ๊ตฌ์กฐ์ฒด๋กœ ๊ฐ์Œ‰๋‹ˆ๋‹ค.

    • ๊ฒฐ๊ณผ๋ฅผ Result ํƒ€์ž…์œผ๋กœ ๋ณ€ํ™˜ํ•˜์—ฌ HTTP ์ƒํƒœ ์ฝ”๋“œ๋ฅผ ์„ค์ •ํ•˜๊ณ  api.View๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ ์‘๋‹ต์„ ์ฒ˜๋ฆฌํ•ฉ๋‹ˆ๋‹ค.

6. Script ๋ฉ”์„œ๋“œ

  • ์—ญํ• : ์ฃผ์–ด์ง„ ์Šคํฌ๋ฆฝํŠธ๋ฅผ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค.

  • ๋™์ž‘ ๋ฐฉ์‹:

    • ๋ช…๋ น์ค„ ์ธ์ž๋ฅผ ํŒŒ์‹ฑํ•˜์—ฌ ์Šคํฌ๋ฆฝํŠธ ์ด๋ฆ„์„ ์ถ”์ถœํ•ฉ๋‹ˆ๋‹ค.

    • --version ๋˜๋Š” -v ์˜ต์…˜์„ ์ฒ˜๋ฆฌํ•ฉ๋‹ˆ๋‹ค.

    • Ref ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ ์Šคํฌ๋ฆฝํŠธ ๋งต์„ ๊ฐ€์ ธ์˜ต๋‹ˆ๋‹ค. ํ•ด๋‹น ์Šคํฌ๋ฆฝํŠธ๊ฐ€ ์—†์œผ๋ฉด ๋„์›€๋ง ์Šคํฌ๋ฆฝํŠธ๋ฅผ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค.

    • ์Šคํฌ๋ฆฝํŠธ๊ฐ€ ์กด์žฌํ•˜๋ฉด ReadArg๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ ์ธ์ž๋ฅผ ์ฝ๊ณ  ExecScript๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ ์Šคํฌ๋ฆฝํŠธ๋ฅผ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋ ‡์ง€ ์•Š์œผ๋ฉด DefaultScript๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ ๊ธฐ๋ณธ ์Šคํฌ๋ฆฝํŠธ๋ฅผ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค.

7. DefaultScript ๋ฉ”์„œ๋“œ

  • ์—ญํ• : ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ ์Šคํฌ๋ฆฝํŠธ ๋ช…๋ น์–ด ๋ชฉ๋ก์„ ์ถœ๋ ฅํ•ฉ๋‹ˆ๋‹ค.

  • ๋™์ž‘ ๋ฐฉ์‹:

    • Ref ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ ์Šคํฌ๋ฆฝํŠธ ๋งต์„ ๊ฐ€์ ธ์˜ต๋‹ˆ๋‹ค.

    • ๋ช…๋ น์–ด ๋ชฉ๋ก์„ ์ž‘์„ฑํ•˜๊ณ  ์ตœ๋Œ€ ๊ธธ์ด๋ฅผ ๊ณ„์‚ฐํ•˜์—ฌ ์ถœ๋ ฅ ํฌ๋งท์„ ์กฐ์ •ํ•ฉ๋‹ˆ๋‹ค.

    • ๊ฐ ์Šคํฌ๋ฆฝํŠธ ๋ช…๋ น์–ด์™€ ์„ค๋ช…์„ ์ถœ๋ ฅํ•ฉ๋‹ˆ๋‹ค.

8. ReadArg ๋ฉ”์„œ๋“œ

  • ์—ญํ• : ๋ช…๋ น์ค„ ์ธ์ž๋ฅผ ํŒŒ์‹ฑํ•˜์—ฌ ๋งต ํ˜•ํƒœ๋กœ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

  • ๋™์ž‘ ๋ฐฉ์‹:

    • ๋ช…๋ น์ค„ ์ธ์ž(argv)๋ฅผ ์ˆœํšŒํ•˜๋ฉฐ ์ •๊ทœ ํ‘œํ˜„์‹์„ ์‚ฌ์šฉํ•˜์—ฌ ํŒŒ๋ผ๋ฏธํ„ฐ ํ˜•์‹์„ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค.

    • ์ง์ˆ˜ ์ธ๋ฑ์Šค์—์„œ ํ‚ค๋ฅผ, ํ™€์ˆ˜ ์ธ๋ฑ์Šค์—์„œ ๊ฐ’์„ ์ถ”์ถœํ•˜์—ฌ ๋งต์— ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค.

9. ExecScript ๋ฉ”์„œ๋“œ

  • ์—ญํ• : ์ฃผ์–ด์ง„ ์Šคํฌ๋ฆฝํŠธ๋ฅผ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค.

  • ๋™์ž‘ ๋ฐฉ์‹:

    • ์Šคํฌ๋ฆฝํŠธ์˜ Args ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ ์ธ์ž๋ฅผ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค.

    • ์Šคํฌ๋ฆฝํŠธ์˜ Main ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ ์Šคํฌ๋ฆฝํŠธ๋ฅผ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค.

10. Service ๋ฉ”์„œ๋“œ

  • ์—ญํ• : ์ฃผ์–ด์ง„ ์„œ๋น„์Šค๋ฅผ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค.

  • ๋™์ž‘ ๋ฐฉ์‹:

    • ๋ช…๋ น์ค„ ์ธ์ž์—์„œ ์„œ๋น„์Šค ์ด๋ฆ„์„ ์ถ”์ถœํ•ฉ๋‹ˆ๋‹ค.

    • run ๋ช…๋ น์–ด๋ฅผ ์ฒ˜๋ฆฌํ•˜์—ฌ RunService ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•ฉ๋‹ˆ๋‹ค.

    • Ref ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ ์„œ๋น„์Šค ๋งต์„ ๊ฐ€์ ธ์˜ต๋‹ˆ๋‹ค. ํ•ด๋‹น ์„œ๋น„์Šค๊ฐ€ ์—†์œผ๋ฉด ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ ์„œ๋น„์Šค ๋ชฉ๋ก์„ ์ถœ๋ ฅํ•ฉ๋‹ˆ๋‹ค.

    • ์กด์žฌํ•˜๋ฉด ํ•ด๋‹น ์„œ๋น„์Šค๋ฅผ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค.

11. RunService ๋ฉ”์„œ๋“œ

  • ์—ญํ• : ์ฃผ์–ด์ง„ ์„œ๋น„์Šค ๋ฐ”์ด๋„ˆ๋ฆฌ๋ฅผ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค.

  • ๋™์ž‘ ๋ฐฉ์‹:

    • ๋ช…๋ น์ค„ ์ธ์ž์—์„œ ์„œ๋น„์Šค ์ด๋ฆ„์„ ์ถ”์ถœํ•ฉ๋‹ˆ๋‹ค.

    • run ๋ช…๋ น์–ด๋ฅผ ์ฒ˜๋ฆฌํ•˜์—ฌ ํ”„๋กœ๊ทธ๋žจ์„ ์ข…๋ฃŒํ•ฉ๋‹ˆ๋‹ค.

    • util.ForkProcess๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ ์„œ๋น„์Šค ๋ฐ”์ด๋„ˆ๋ฆฌ๋ฅผ ํฌํฌ ํ”„๋กœ์„ธ์Šค๋กœ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค.

12. ExecService ๋ฉ”์„œ๋“œ

  • ์—ญํ• : ์ฃผ์–ด์ง„ ์„œ๋น„์Šค๋ฅผ ๋ฐ˜๋ณต์ ์œผ๋กœ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค.

  • ๋™์ž‘ ๋ฐฉ์‹:

    • ๊ฐ€๋น„์ง€ ์ปฌ๋ ‰ํ„ฐ๊ฐ€ ํ™œ์„ฑํ™”๋˜์–ด ์žˆ์œผ๋ฉด ํ™œ์„ฑํ™”ํ•ฉ๋‹ˆ๋‹ค.

    • ์„œ๋น„์Šค์˜ Args์™€ Init ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ ์ดˆ๊ธฐํ™”ํ•ฉ๋‹ˆ๋‹ค.

    • ๋ฌดํ•œ ๋ฃจํ”„์—์„œ ์„œ๋น„์Šค์˜ Main๊ณผ Iterate ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ ๋ฐ˜๋ณต ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค.

    • ํ•„์š”์‹œ ์บ์‹œ๋ฅผ ์ง€์šฐ๊ณ  ๊ฐ€๋น„์ง€ ์ปฌ๋ ‰ํ„ฐ๋ฅผ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค.

์ด์™€ ๊ฐ™์ด ๊ฐ ํ•จ์ˆ˜๋Š” API ํ˜ธ์ถœ, ์Šคํฌ๋ฆฝํŠธ ์‹คํ–‰, ์„œ๋น„์Šค ์‹คํ–‰ ๋“ฑ์˜ ์ž‘์—…์„ ์ฒ˜๋ฆฌํ•˜๊ธฐ ์œ„ํ•œ ๋‹ค์–‘ํ•œ ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•˜๋ฉฐ, ์ฃผ์–ด์ง„ ์ž…๋ ฅ๊ณผ ์„ค์ •์„ ๊ธฐ๋ฐ˜์œผ๋กœ ํ•„์š”ํ•œ ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค.

Last updated