Skip to content

Commit

Permalink
feat(proxy): add registry, runner and other supporting functionality (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
plastikfan committed Dec 4, 2023
1 parent 7cc38de commit d9f7023
Show file tree
Hide file tree
Showing 18 changed files with 349 additions and 115 deletions.
3 changes: 3 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,14 @@
"cSpell.words": [
"bodyclose",
"clif",
"cmds",
"cobrass",
"cubiest",
"deadcode",
"deepcopy",
"depguard",
"dogsled",
"dotenv",
"dupl",
"errcheck",
"exportloopref",
Expand Down Expand Up @@ -44,6 +46,7 @@
"onsi",
"Pixa",
"prealloc",
"promptui",
"repotoken",
"samber",
"sidewalk",
Expand Down
52 changes: 45 additions & 7 deletions Taskfile.yml
Original file line number Diff line number Diff line change
Expand Up @@ -50,10 +50,15 @@ tasks:
generates:
- "{{.DIST_DIR}}/{{.TARGET_OS}}/{{.BINARY_NAME}}{{.BINARY_EXT}}"

b:
bw:
cmds:
- task: build-w

bm:
cmds:
- task: build-m


build-w:
cmds:
- task: build_generic
Expand All @@ -77,13 +82,17 @@ tasks:

# === deploy ================================================

d:
dw:
cmds:
- task: deploy
- task: deploy-w

dm:
cmds:
- task: deploy-m

# currently, this is hardcoded for windows
#
deploy:
deploy-w:
vars:
BINARY_EXT: .exe
TARGET_OS: windows
Expand All @@ -104,11 +113,40 @@ tasks:
- test -f {{.DEPLOY_BINARY}}
- test -f {{.DEPLOY_DIR}}/{{.ACTIVE_US}}

tbd:
# currently, this is hardcoded for mac. these deploy tasks need to be improved
# to remove the duplicated code
#
deploy-m:
vars:
TARGET_OS: darwin
DEPLOY_BINARY: "{{.DIST_DIR}}/{{.TARGET_OS}}/{{.BINARY_NAME}}"
DEPLOY_US: "{{.DEPLOY_DIR}}/{{.ACTIVE_US}}"

cmds:
- echo "deploying to location (.env) DEPLOY_TO ==> '$DEPLOY_TO'"
- /bin/cp -f {{.DEPLOY_BINARY}} $DEPLOY_TO
- /bin/cp -f {{.DEPLOY_DIR}}/{{.ACTIVE_US}} $DEPLOY_TO

generates:
- $DEPLOY_TO/{{.DEPLOY_BINARY}}
- $DEPLOY_TO/{{.ACTIVE_US}}

preconditions:
- test $DEPLOY_TO
- test -f {{.DEPLOY_BINARY}}
- test -f {{.DEPLOY_DIR}}/{{.ACTIVE_US}}

tbw:
cmds:
- task: t
- task: bw
- task: dw

tbm:
cmds:
- task: t
- task: b
- task: d
- task: bm
- task: dm

# === ginkgo ================================================

Expand Down
Binary file added dist/darwin/pixa
Binary file not shown.
47 changes: 47 additions & 0 deletions resources/doc/DESIGN-RESEARCH.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# 🧩 Design Notes

This document serves as a place to contain notes/ideas about decisions made in design. It is not meant to be taken as gospel, it really is just a dumping ground for brain-storming sessions. Usually, design notes are just written into github issues, but the problem with that is that issues are closed and those notes get lost in history and are thus difficult to re-reference.

## 🚀 Workflow Patterns

🔎 See [Control-Flow Patterns](http://www.workflowpatterns.com/patterns/control/)

Actually, the referenced site looks to be very good as it deals with scenarios that I have been wrestling with in various parts of my snivilised projects, but I have dealt with them on an adhoc manner, coming up with my own way of doing things rather that looking at established patterns. This can serve as a very good reference. A lot of these patterns are relevant for web workflows, but they can be adapted to be used in other contexts too.

## 🧭 DDD in Go

🔎 See [how to impl ddd in go](https://programmingpercy.tech/blog/how-to-domain-driven-design-ddd-golang/)

* in ddd, a value object has no behaviour it just holds some state (ie it is a placeholder for some information). it is considered immutable and is unidentifiable.

* an entity is identifiable (by an ID)

* so inside the traversal callback, we create a value-object that then allows us the create th path-finder and whatever else is needed

* functionality does not go inside entity objects, they should be inside an aggregate. an aggregate combines multiple entities to create a full object. to create an aggregate, you must identify which of the entities is the root entity. an aggregate can also contain value-objects

* aggregates do not contain the marshalling/persistence tags (json/xml) for each of its members. the aggregate is not supposed to be ab to define the formatting of its members.

the reasons are:

* aggregates are stored by repositories (see repository pattern). the repository (typically hidden behind an interface) is a compound object which will contain many aggregates of a type. you might have a repository for mongo-db, another for ms-sql etc... ~ dao. Personally, I would do this a bit different; I would prefer a single repository that could be configured with different data access providers.

* a service is a higher level of abstraction than the repository. the repository will contain just a single type of entity, but typically in a system, we need many repositories. a service will couple together these repositories.

* use functional composition as a helper for creating factories (configuration pattern)

* sample needs an execution chain of objects to complete work, because multiple executions of magick with varying parameters will be required. In the full run, this chain is a chain of 1.

## Prompting for input in Command line

See: [promptui](https://github.com/manifoldco/promptui)

In resume scenarios, we need to be able to show a menu of the resume files found and let the user select which to use, using the up/down keys.

## sync.Pool

🔎 See: [Think In sync.pool](https://www.sobyte.net/post/2022-03/think-in-sync-pool/), [Martin Fowler - Registry](https://martinfowler.com/eaaCatalog/registry.html)

For each TraverseItem to be processed, we need a way to enter processing. We could create a new runner for every item. However, during long batch runs, that would mean creating and releasing many objects, placing more pressure on the GC. To avoid this, we can employ sync.pool, and let that allocate runners. In fact, we create a runner registry that wraps the object pool and we interact with the registry instead.

Ordinarily, the Registry would be contained within a service as the service would play host to many registries. But in Pixa, we only have a single registry, so it is not worth the overhead to introduce a service; doing so would be for the sake of it.
15 changes: 10 additions & 5 deletions src/app/command/bootstrap_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,16 +38,21 @@ func (j *DetectorStub) Scan() language.Tag {
var _ = Describe("Bootstrap", Ordered, func() {

var (
repo string
l10nPath string
nfs storage.VirtualFS
repo string
l10nPath string
configPath string
nfs storage.VirtualFS
)

BeforeAll(func() {
nfs = storage.UseNativeFS()
repo = helpers.Repo(filepath.Join("..", "..", ".."))

l10nPath = helpers.Path(repo, filepath.Join("test", "data", "l10n"))
Expect(matchers.AsDirectory(l10nPath)).To(matchers.ExistInFS(nfs))

configPath = filepath.Join(repo, "test", "data", "configuration")
Expect(matchers.AsDirectory(configPath)).To(matchers.ExistInFS(nfs))
})

Context("given: root defined with magick sub-command", func() {
Expand All @@ -58,8 +63,8 @@ var _ = Describe("Bootstrap", Ordered, func() {
co.Executor = &ExecutorStub{
Name: "magick",
}
co.Config.Name = "pixa-test"
co.Config.ConfigPath = filepath.Join(repo, "test", "data", "configuration")
co.Config.Name = helpers.PixaConfigTestFilename
co.Config.ConfigPath = configPath
})
Expect(rootCmd).NotTo(BeNil())
})
Expand Down
27 changes: 12 additions & 15 deletions src/app/command/root-cmd_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,17 +20,22 @@ type rootTE struct {

var _ = Describe("RootCmd", Ordered, func() {
var (
repo string
l10nPath string
nfs storage.VirtualFS
tester helpers.CommandTester
repo string
l10nPath string
configPath string
nfs storage.VirtualFS
tester helpers.CommandTester
)

BeforeAll(func() {
nfs = storage.UseNativeFS()
repo = helpers.Repo(filepath.Join("..", "..", ".."))

l10nPath = helpers.Path(repo, filepath.Join("test", "data", "l10n"))
Expect(matchers.AsDirectory(l10nPath)).To(matchers.ExistInFS(nfs))

configPath = filepath.Join(repo, "test", "data", "configuration")
Expect(matchers.AsDirectory(configPath)).To(matchers.ExistInFS(nfs))
})

BeforeEach(func() {
Expand All @@ -42,23 +47,15 @@ var _ = Describe("RootCmd", Ordered, func() {
co.Executor = &ExecutorStub{
Name: "magick",
}
co.Config.Name = helpers.PixaConfigTestFilename
co.Config.ConfigPath = configPath
}),
}
})

DescribeTable("dummy magick",
func(entry *rootTE) {
bootstrap := command.Bootstrap{}
tester = helpers.CommandTester{
Args: entry.commandLine,
Root: bootstrap.Root(func(co *command.ConfigureOptionsInfo) {
co.Detector = &DetectorStub{}
co.Executor = &ExecutorStub{
Name: "magick",
}
}),
}

tester.Args = entry.commandLine
_, err := tester.Execute()
Expect(err).Error().To(BeNil())
},
Expand Down
5 changes: 3 additions & 2 deletions src/app/command/shrink-cmd_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,15 +41,16 @@ func expectValidShrinkCmdInvocation(entry *shrinkTE) {
}...)

repo := helpers.Repo(filepath.Join("..", "..", ".."))
configPath := filepath.Join(repo, "test", "data", "configuration")
tester := helpers.CommandTester{
Args: append(options, entry.args...),
Root: bootstrap.Root(func(co *command.ConfigureOptionsInfo) {
co.Detector = &DetectorStub{}
co.Executor = &ExecutorStub{
Name: "magick",
}
co.Config.Name = "pixa-test"
co.Config.ConfigPath = filepath.Join(repo, "test", "data", "configuration")
co.Config.Name = helpers.PixaConfigTestFilename
co.Config.ConfigPath = configPath
}),
}

Expand Down
12 changes: 3 additions & 9 deletions src/app/proxy/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ func expectValidShrinkCmdInvocation(entry *configTE) {
co.Executor = &helpers.ExecutorStub{
Name: prog,
}
co.Config.Name = "pixa-test"
co.Config.Name = helpers.PixaConfigTestFilename
co.Config.ConfigPath = filepath.Join(repo, "test", "data", "configuration")
}),
}
Expand All @@ -59,12 +59,6 @@ type configTE struct {
assert func(entry *configTE, actual any)
}

func reason(field string, expected, actual any) string {
return fmt.Sprintf("🔥 expected field '%v' to be '%v', but was '%v'\n",
field, expected, actual,
)
}

var _ = Describe("Config", func() {
var (
config configuration.ViperConfig
Expand All @@ -75,8 +69,8 @@ var _ = Describe("Config", func() {
viper.Reset()
config = &configuration.GlobalViperConfig{}

config.SetConfigType("yml")
config.SetConfigName("pixa-test")
config.SetConfigType(helpers.PixaConfigType)
config.SetConfigName(helpers.PixaConfigTestFilename)

if _, err := os.Lstat(relative); err != nil {
Fail("🔥 can't find config path")
Expand Down
Loading

0 comments on commit d9f7023

Please sign in to comment.