Worker: wrap api.ClientWithResponsesInterface in a local interface

This makes it possible to locally create a mock object for the API client.
This commit is contained in:
Sybren A. Stüvel 2022-02-22 17:13:04 +01:00
parent 19b86172b4
commit b462e8db1a
5 changed files with 379 additions and 9 deletions

33
internal/worker/client.go Normal file
View File

@ -0,0 +1,33 @@
package worker
/* ***** BEGIN GPL LICENSE BLOCK *****
*
* Original Code Copyright (C) 2022 Blender Foundation.
*
* This file is part of Flamenco.
*
* Flamenco is free software: you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later
* version.
*
* Flamenco is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* Flamenco. If not, see <https://www.gnu.org/licenses/>.
*
* ***** END GPL LICENSE BLOCK ***** */
import (
"gitlab.com/blender/flamenco-ng-poc/pkg/api"
)
// Generate the mock for the client interface.
//go:generate go run github.com/golang/mock/mockgen -destination mocks/client.gen.go -package mocks gitlab.com/blender/flamenco-ng-poc/internal/worker FlamencoClient
// FlamencoClient is a wrapper for api.ClientWithResponsesInterface so that locally mocks can be created.
type FlamencoClient interface {
api.ClientWithResponsesInterface
}

View File

@ -43,11 +43,11 @@ var (
// Listener listens to the result of task and command execution, and sends it to the Manager.
type Listener struct {
doneWg *sync.WaitGroup
client api.ClientWithResponsesInterface
client FlamencoClient
}
// NewListener creates a new Listener that will send updates to the API client.
func NewListener(client api.ClientWithResponsesInterface) *Listener {
func NewListener(client FlamencoClient) *Listener {
l := &Listener{
doneWg: new(sync.WaitGroup),
client: client,

View File

@ -0,0 +1,337 @@
// Code generated by MockGen. DO NOT EDIT.
// Source: gitlab.com/blender/flamenco-ng-poc/internal/worker (interfaces: FlamencoClient)
// Package mocks is a generated GoMock package.
package mocks
import (
context "context"
io "io"
reflect "reflect"
gomock "github.com/golang/mock/gomock"
api "gitlab.com/blender/flamenco-ng-poc/pkg/api"
)
// MockFlamencoClient is a mock of FlamencoClient interface.
type MockFlamencoClient struct {
ctrl *gomock.Controller
recorder *MockFlamencoClientMockRecorder
}
// MockFlamencoClientMockRecorder is the mock recorder for MockFlamencoClient.
type MockFlamencoClientMockRecorder struct {
mock *MockFlamencoClient
}
// NewMockFlamencoClient creates a new mock instance.
func NewMockFlamencoClient(ctrl *gomock.Controller) *MockFlamencoClient {
mock := &MockFlamencoClient{ctrl: ctrl}
mock.recorder = &MockFlamencoClientMockRecorder{mock}
return mock
}
// EXPECT returns an object that allows the caller to indicate expected use.
func (m *MockFlamencoClient) EXPECT() *MockFlamencoClientMockRecorder {
return m.recorder
}
// FetchJobWithResponse mocks base method.
func (m *MockFlamencoClient) FetchJobWithResponse(arg0 context.Context, arg1 string, arg2 ...api.RequestEditorFn) (*api.FetchJobResponse, error) {
m.ctrl.T.Helper()
varargs := []interface{}{arg0, arg1}
for _, a := range arg2 {
varargs = append(varargs, a)
}
ret := m.ctrl.Call(m, "FetchJobWithResponse", varargs...)
ret0, _ := ret[0].(*api.FetchJobResponse)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// FetchJobWithResponse indicates an expected call of FetchJobWithResponse.
func (mr *MockFlamencoClientMockRecorder) FetchJobWithResponse(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
varargs := append([]interface{}{arg0, arg1}, arg2...)
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FetchJobWithResponse", reflect.TypeOf((*MockFlamencoClient)(nil).FetchJobWithResponse), varargs...)
}
// GetJobTypesWithResponse mocks base method.
func (m *MockFlamencoClient) GetJobTypesWithResponse(arg0 context.Context, arg1 ...api.RequestEditorFn) (*api.GetJobTypesResponse, error) {
m.ctrl.T.Helper()
varargs := []interface{}{arg0}
for _, a := range arg1 {
varargs = append(varargs, a)
}
ret := m.ctrl.Call(m, "GetJobTypesWithResponse", varargs...)
ret0, _ := ret[0].(*api.GetJobTypesResponse)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// GetJobTypesWithResponse indicates an expected call of GetJobTypesWithResponse.
func (mr *MockFlamencoClientMockRecorder) GetJobTypesWithResponse(arg0 interface{}, arg1 ...interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
varargs := append([]interface{}{arg0}, arg1...)
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetJobTypesWithResponse", reflect.TypeOf((*MockFlamencoClient)(nil).GetJobTypesWithResponse), varargs...)
}
// RegisterWorkerWithBodyWithResponse mocks base method.
func (m *MockFlamencoClient) RegisterWorkerWithBodyWithResponse(arg0 context.Context, arg1 string, arg2 io.Reader, arg3 ...api.RequestEditorFn) (*api.RegisterWorkerResponse, error) {
m.ctrl.T.Helper()
varargs := []interface{}{arg0, arg1, arg2}
for _, a := range arg3 {
varargs = append(varargs, a)
}
ret := m.ctrl.Call(m, "RegisterWorkerWithBodyWithResponse", varargs...)
ret0, _ := ret[0].(*api.RegisterWorkerResponse)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// RegisterWorkerWithBodyWithResponse indicates an expected call of RegisterWorkerWithBodyWithResponse.
func (mr *MockFlamencoClientMockRecorder) RegisterWorkerWithBodyWithResponse(arg0, arg1, arg2 interface{}, arg3 ...interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
varargs := append([]interface{}{arg0, arg1, arg2}, arg3...)
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RegisterWorkerWithBodyWithResponse", reflect.TypeOf((*MockFlamencoClient)(nil).RegisterWorkerWithBodyWithResponse), varargs...)
}
// RegisterWorkerWithResponse mocks base method.
func (m *MockFlamencoClient) RegisterWorkerWithResponse(arg0 context.Context, arg1 api.RegisterWorkerJSONRequestBody, arg2 ...api.RequestEditorFn) (*api.RegisterWorkerResponse, error) {
m.ctrl.T.Helper()
varargs := []interface{}{arg0, arg1}
for _, a := range arg2 {
varargs = append(varargs, a)
}
ret := m.ctrl.Call(m, "RegisterWorkerWithResponse", varargs...)
ret0, _ := ret[0].(*api.RegisterWorkerResponse)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// RegisterWorkerWithResponse indicates an expected call of RegisterWorkerWithResponse.
func (mr *MockFlamencoClientMockRecorder) RegisterWorkerWithResponse(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
varargs := append([]interface{}{arg0, arg1}, arg2...)
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RegisterWorkerWithResponse", reflect.TypeOf((*MockFlamencoClient)(nil).RegisterWorkerWithResponse), varargs...)
}
// ScheduleTaskWithResponse mocks base method.
func (m *MockFlamencoClient) ScheduleTaskWithResponse(arg0 context.Context, arg1 ...api.RequestEditorFn) (*api.ScheduleTaskResponse, error) {
m.ctrl.T.Helper()
varargs := []interface{}{arg0}
for _, a := range arg1 {
varargs = append(varargs, a)
}
ret := m.ctrl.Call(m, "ScheduleTaskWithResponse", varargs...)
ret0, _ := ret[0].(*api.ScheduleTaskResponse)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// ScheduleTaskWithResponse indicates an expected call of ScheduleTaskWithResponse.
func (mr *MockFlamencoClientMockRecorder) ScheduleTaskWithResponse(arg0 interface{}, arg1 ...interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
varargs := append([]interface{}{arg0}, arg1...)
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ScheduleTaskWithResponse", reflect.TypeOf((*MockFlamencoClient)(nil).ScheduleTaskWithResponse), varargs...)
}
// SignOffWithResponse mocks base method.
func (m *MockFlamencoClient) SignOffWithResponse(arg0 context.Context, arg1 ...api.RequestEditorFn) (*api.SignOffResponse, error) {
m.ctrl.T.Helper()
varargs := []interface{}{arg0}
for _, a := range arg1 {
varargs = append(varargs, a)
}
ret := m.ctrl.Call(m, "SignOffWithResponse", varargs...)
ret0, _ := ret[0].(*api.SignOffResponse)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// SignOffWithResponse indicates an expected call of SignOffWithResponse.
func (mr *MockFlamencoClientMockRecorder) SignOffWithResponse(arg0 interface{}, arg1 ...interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
varargs := append([]interface{}{arg0}, arg1...)
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SignOffWithResponse", reflect.TypeOf((*MockFlamencoClient)(nil).SignOffWithResponse), varargs...)
}
// SignOnWithBodyWithResponse mocks base method.
func (m *MockFlamencoClient) SignOnWithBodyWithResponse(arg0 context.Context, arg1 string, arg2 io.Reader, arg3 ...api.RequestEditorFn) (*api.SignOnResponse, error) {
m.ctrl.T.Helper()
varargs := []interface{}{arg0, arg1, arg2}
for _, a := range arg3 {
varargs = append(varargs, a)
}
ret := m.ctrl.Call(m, "SignOnWithBodyWithResponse", varargs...)
ret0, _ := ret[0].(*api.SignOnResponse)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// SignOnWithBodyWithResponse indicates an expected call of SignOnWithBodyWithResponse.
func (mr *MockFlamencoClientMockRecorder) SignOnWithBodyWithResponse(arg0, arg1, arg2 interface{}, arg3 ...interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
varargs := append([]interface{}{arg0, arg1, arg2}, arg3...)
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SignOnWithBodyWithResponse", reflect.TypeOf((*MockFlamencoClient)(nil).SignOnWithBodyWithResponse), varargs...)
}
// SignOnWithResponse mocks base method.
func (m *MockFlamencoClient) SignOnWithResponse(arg0 context.Context, arg1 api.SignOnJSONRequestBody, arg2 ...api.RequestEditorFn) (*api.SignOnResponse, error) {
m.ctrl.T.Helper()
varargs := []interface{}{arg0, arg1}
for _, a := range arg2 {
varargs = append(varargs, a)
}
ret := m.ctrl.Call(m, "SignOnWithResponse", varargs...)
ret0, _ := ret[0].(*api.SignOnResponse)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// SignOnWithResponse indicates an expected call of SignOnWithResponse.
func (mr *MockFlamencoClientMockRecorder) SignOnWithResponse(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
varargs := append([]interface{}{arg0, arg1}, arg2...)
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SignOnWithResponse", reflect.TypeOf((*MockFlamencoClient)(nil).SignOnWithResponse), varargs...)
}
// SubmitJobWithBodyWithResponse mocks base method.
func (m *MockFlamencoClient) SubmitJobWithBodyWithResponse(arg0 context.Context, arg1 string, arg2 io.Reader, arg3 ...api.RequestEditorFn) (*api.SubmitJobResponse, error) {
m.ctrl.T.Helper()
varargs := []interface{}{arg0, arg1, arg2}
for _, a := range arg3 {
varargs = append(varargs, a)
}
ret := m.ctrl.Call(m, "SubmitJobWithBodyWithResponse", varargs...)
ret0, _ := ret[0].(*api.SubmitJobResponse)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// SubmitJobWithBodyWithResponse indicates an expected call of SubmitJobWithBodyWithResponse.
func (mr *MockFlamencoClientMockRecorder) SubmitJobWithBodyWithResponse(arg0, arg1, arg2 interface{}, arg3 ...interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
varargs := append([]interface{}{arg0, arg1, arg2}, arg3...)
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SubmitJobWithBodyWithResponse", reflect.TypeOf((*MockFlamencoClient)(nil).SubmitJobWithBodyWithResponse), varargs...)
}
// SubmitJobWithResponse mocks base method.
func (m *MockFlamencoClient) SubmitJobWithResponse(arg0 context.Context, arg1 api.SubmitJobJSONRequestBody, arg2 ...api.RequestEditorFn) (*api.SubmitJobResponse, error) {
m.ctrl.T.Helper()
varargs := []interface{}{arg0, arg1}
for _, a := range arg2 {
varargs = append(varargs, a)
}
ret := m.ctrl.Call(m, "SubmitJobWithResponse", varargs...)
ret0, _ := ret[0].(*api.SubmitJobResponse)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// SubmitJobWithResponse indicates an expected call of SubmitJobWithResponse.
func (mr *MockFlamencoClientMockRecorder) SubmitJobWithResponse(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
varargs := append([]interface{}{arg0, arg1}, arg2...)
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SubmitJobWithResponse", reflect.TypeOf((*MockFlamencoClient)(nil).SubmitJobWithResponse), varargs...)
}
// TaskUpdateWithBodyWithResponse mocks base method.
func (m *MockFlamencoClient) TaskUpdateWithBodyWithResponse(arg0 context.Context, arg1, arg2 string, arg3 io.Reader, arg4 ...api.RequestEditorFn) (*api.TaskUpdateResponse, error) {
m.ctrl.T.Helper()
varargs := []interface{}{arg0, arg1, arg2, arg3}
for _, a := range arg4 {
varargs = append(varargs, a)
}
ret := m.ctrl.Call(m, "TaskUpdateWithBodyWithResponse", varargs...)
ret0, _ := ret[0].(*api.TaskUpdateResponse)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// TaskUpdateWithBodyWithResponse indicates an expected call of TaskUpdateWithBodyWithResponse.
func (mr *MockFlamencoClientMockRecorder) TaskUpdateWithBodyWithResponse(arg0, arg1, arg2, arg3 interface{}, arg4 ...interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
varargs := append([]interface{}{arg0, arg1, arg2, arg3}, arg4...)
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "TaskUpdateWithBodyWithResponse", reflect.TypeOf((*MockFlamencoClient)(nil).TaskUpdateWithBodyWithResponse), varargs...)
}
// TaskUpdateWithResponse mocks base method.
func (m *MockFlamencoClient) TaskUpdateWithResponse(arg0 context.Context, arg1 string, arg2 api.TaskUpdateJSONRequestBody, arg3 ...api.RequestEditorFn) (*api.TaskUpdateResponse, error) {
m.ctrl.T.Helper()
varargs := []interface{}{arg0, arg1, arg2}
for _, a := range arg3 {
varargs = append(varargs, a)
}
ret := m.ctrl.Call(m, "TaskUpdateWithResponse", varargs...)
ret0, _ := ret[0].(*api.TaskUpdateResponse)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// TaskUpdateWithResponse indicates an expected call of TaskUpdateWithResponse.
func (mr *MockFlamencoClientMockRecorder) TaskUpdateWithResponse(arg0, arg1, arg2 interface{}, arg3 ...interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
varargs := append([]interface{}{arg0, arg1, arg2}, arg3...)
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "TaskUpdateWithResponse", reflect.TypeOf((*MockFlamencoClient)(nil).TaskUpdateWithResponse), varargs...)
}
// WorkerStateChangedWithBodyWithResponse mocks base method.
func (m *MockFlamencoClient) WorkerStateChangedWithBodyWithResponse(arg0 context.Context, arg1 string, arg2 io.Reader, arg3 ...api.RequestEditorFn) (*api.WorkerStateChangedResponse, error) {
m.ctrl.T.Helper()
varargs := []interface{}{arg0, arg1, arg2}
for _, a := range arg3 {
varargs = append(varargs, a)
}
ret := m.ctrl.Call(m, "WorkerStateChangedWithBodyWithResponse", varargs...)
ret0, _ := ret[0].(*api.WorkerStateChangedResponse)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// WorkerStateChangedWithBodyWithResponse indicates an expected call of WorkerStateChangedWithBodyWithResponse.
func (mr *MockFlamencoClientMockRecorder) WorkerStateChangedWithBodyWithResponse(arg0, arg1, arg2 interface{}, arg3 ...interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
varargs := append([]interface{}{arg0, arg1, arg2}, arg3...)
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "WorkerStateChangedWithBodyWithResponse", reflect.TypeOf((*MockFlamencoClient)(nil).WorkerStateChangedWithBodyWithResponse), varargs...)
}
// WorkerStateChangedWithResponse mocks base method.
func (m *MockFlamencoClient) WorkerStateChangedWithResponse(arg0 context.Context, arg1 api.WorkerStateChangedJSONRequestBody, arg2 ...api.RequestEditorFn) (*api.WorkerStateChangedResponse, error) {
m.ctrl.T.Helper()
varargs := []interface{}{arg0, arg1}
for _, a := range arg2 {
varargs = append(varargs, a)
}
ret := m.ctrl.Call(m, "WorkerStateChangedWithResponse", varargs...)
ret0, _ := ret[0].(*api.WorkerStateChangedResponse)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// WorkerStateChangedWithResponse indicates an expected call of WorkerStateChangedWithResponse.
func (mr *MockFlamencoClientMockRecorder) WorkerStateChangedWithResponse(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
varargs := append([]interface{}{arg0, arg1}, arg2...)
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "WorkerStateChangedWithResponse", reflect.TypeOf((*MockFlamencoClient)(nil).WorkerStateChangedWithResponse), varargs...)
}
// WorkerStateWithResponse mocks base method.
func (m *MockFlamencoClient) WorkerStateWithResponse(arg0 context.Context, arg1 ...api.RequestEditorFn) (*api.WorkerStateResponse, error) {
m.ctrl.T.Helper()
varargs := []interface{}{arg0}
for _, a := range arg1 {
varargs = append(varargs, a)
}
ret := m.ctrl.Call(m, "WorkerStateWithResponse", varargs...)
ret0, _ := ret[0].(*api.WorkerStateResponse)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// WorkerStateWithResponse indicates an expected call of WorkerStateWithResponse.
func (mr *MockFlamencoClientMockRecorder) WorkerStateWithResponse(arg0 interface{}, arg1 ...interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
varargs := append([]interface{}{arg0}, arg1...)
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "WorkerStateWithResponse", reflect.TypeOf((*MockFlamencoClient)(nil).WorkerStateWithResponse), varargs...)
}

View File

@ -44,7 +44,7 @@ var (
// registerOrSignOn tries to sign on, and if that fails (or there are no credentials) tries to register.
// Returns an authenticated Flamenco OpenAPI client.
func RegisterOrSignOn(ctx context.Context, configWrangler FileConfigWrangler) (
client api.ClientWithResponsesInterface, startupState api.WorkerStatus,
client FlamencoClient, startupState api.WorkerStatus,
) {
// Load configuration
cfg, err := loadConfig(configWrangler)
@ -93,7 +93,7 @@ func RegisterOrSignOn(ctx context.Context, configWrangler FileConfigWrangler) (
// (Re-)register ourselves at the Manager.
// Logs a fatal error if unsuccesful.
func register(ctx context.Context, cfg WorkerConfig, client api.ClientWithResponsesInterface) WorkerCredentials {
func register(ctx context.Context, cfg WorkerConfig, client FlamencoClient) WorkerCredentials {
// Construct our new password.
secret := make([]byte, 32)
if _, err := rand.Read(secret); err != nil {
@ -132,7 +132,7 @@ func register(ctx context.Context, cfg WorkerConfig, client api.ClientWithRespon
// repeatSignOnUntilAnswer tries to sign on, and only returns when it has been able to reach the Manager.
// Return still doesn't mean that the sign-on was succesful; inspect the returned error.
func repeatSignOnUntilAnswer(ctx context.Context, cfg WorkerConfig, client api.ClientWithResponsesInterface) (api.WorkerStatus, error) {
func repeatSignOnUntilAnswer(ctx context.Context, cfg WorkerConfig, client FlamencoClient) (api.WorkerStatus, error) {
waitTime := 0 * time.Second
for {
select {
@ -157,7 +157,7 @@ func repeatSignOnUntilAnswer(ctx context.Context, cfg WorkerConfig, client api.C
}
// signOn tells the Manager we're alive and returns the status the Manager tells us to go to.
func signOn(ctx context.Context, cfg WorkerConfig, client api.ClientWithResponsesInterface) (api.WorkerStatus, error) {
func signOn(ctx context.Context, cfg WorkerConfig, client FlamencoClient) (api.WorkerStatus, error) {
logger := log.With().Str("manager", cfg.Manager).Logger()
req := api.SignOnJSONRequestBody{
@ -206,7 +206,7 @@ func mustHostname() string {
}
// authenticatedClient constructs a Flamenco client with the given credentials.
func authenticatedClient(cfg WorkerConfig, creds WorkerCredentials) api.ClientWithResponsesInterface {
func authenticatedClient(cfg WorkerConfig, creds WorkerCredentials) FlamencoClient {
flamenco, err := api.NewClientWithResponses(
cfg.Manager,

View File

@ -13,7 +13,7 @@ type Worker struct {
doneChan chan struct{}
doneWg *sync.WaitGroup
client api.ClientWithResponsesInterface
client FlamencoClient
state api.WorkerStatus
stateStarters map[api.WorkerStatus]StateStarter // gotoStateXXX functions
@ -30,7 +30,7 @@ type TaskRunner interface {
// NewWorker constructs and returns a new Worker.
func NewWorker(
flamenco api.ClientWithResponsesInterface,
flamenco FlamencoClient,
taskRunner TaskRunner,
) *Worker {