Conversation
2dd3260 to
1f8c203
Compare
|
I had a quick look, I have few feedback for now:
|
1f8c203 to
3a24759
Compare
f72dd7b to
b9e1cb6
Compare
b9e1cb6 to
28482ce
Compare
If API accepts service then who manage databases to get them? The flow right now is: If you want to accept
To avoid api package becoming bigger. And I felt that manager struct belongs more to service (as it only operates on service). Moving this to api means also that api imports container package so it measn it depends on service and container package rather then service itself.
From discussion on discord we end up with: The array keeps the order or parameters and it's more deterministic definition of service so the array is preferable way here. The second thing is that definitions and protobuf should be same if possible, so if we have array we will have them in mesg.yaml as well (@antho1404 please confim that what I wrote cover our discussion or add missing part) |
28482ce to
d015140
Compare
|
This PR is too big, it needs to be split to smaller ones with explanatory commit messages. |
Not exactly.
|
d898cd3 to
2bf586d
Compare
2bf586d to
4db9b62
Compare
…ggestion Service refactor nico suggestion
…to service-refactor
|
@antho1404 @ilgooz please review. |
antho1404
left a comment
There was a problem hiding this comment.
few feedback but I didn't do a full validation yet and no testing yet.
It will take quite some time to test correctly everything. Again I strongly encourage to split this PR as many things are independent
| return nil, err | ||
| } | ||
| defer resp.Body.Close() | ||
| if err := archive.Untar(resp.Body, contextDir, nil); err != nil { |
There was a problem hiding this comment.
why changing back, why not keep using the DeployService that takes a reader and will simplify the function and also put all the logic in the same place if we need to do some extra work for the tar
There was a problem hiding this comment.
we wanted service to accept contextDir as arguments. So there are few cases here:
- api receives io.Reader that could be read only once
- api needs to
formalizeContext(remove .git etc...) so it needs to extract the tar - service needs a directory to calculate the hash
- service needs tar.Reader to pass it to docker deploy api
So combining all this either service will receive io.reader, extract tar, calc the hash and then archive it back, or the other way.
There was a problem hiding this comment.
that's not my point here, why not use DeployService(resp.Body, ...) and have a pseudo function like that
if isGit {
dir = createTmp()
gitClone(arg, dir)
return deploy(dir)
}
resp = http.Get(arg)
return DeployService(resp.Body, ...)
Here we have only one function responsible for the untar, not 2 and nothing else changes and we still have the context
There was a problem hiding this comment.
To send status about Service downloaded. Also it seems more readable to me.
| return fmt.Sprintf(`%s Dockerfile exists | ||
| %s mesg.yml is valid | ||
| %s Service is valid`, pretty.SuccessSign, pretty.SuccessSign, pretty.SuccessSign), nil | ||
| return fmt.Sprintf(`%s mesg.yml is valid`, pretty.SuccessSign), nil |
There was a problem hiding this comment.
Agree with that argument but we still need to validate that the service contains a dockerfile
| return string(content), err | ||
| } | ||
|
|
||
| func taskByKey(s *coreapi.Service, key string) *coreapi.Task { |
There was a problem hiding this comment.
should return an error if not found to avoid risk of null pointer
There was a problem hiding this comment.
we can but we can check for the null as well, it's just a helper function only used inside this file.
There was a problem hiding this comment.
just seems better to adopt this pattern all the time. Also we are returning the error anyway just after so let's get the error from the function itself
There was a problem hiding this comment.
I feel it's not a really good pattern in Go to return a pointer without error.
I speak about this with Hubert about should we keep pointer in the data structure of service or not. We didn't find a good solution.
In both TypeScript and in Swift, they force to check if the variable / pointer is nil / undefined before accessing a value in it. This is not something that the Go compiler enforce. I feel it opens the place for many nil pointer error...
What about removing all pointers in the struct of the service? Like this, for example, this function taskByKey, will need to have the following signature: taskByKey(s coreapi.Service, key string) (coreapi.Task, error).
It will consume more memory, but we are forced to follow a good pattern.
There was a problem hiding this comment.
the pointer discussion is something else, the problem will be the same. Either we test something based on the value returned or based on an error.
After I kind of agree if it's pure data we don't necessary need pointers as long as it's not huge data and not really important that are present everywhere in all the modules. For this one I don't mind keeping the pointers. I don't see any really good reason to change it
There was a problem hiding this comment.
we can change to error, it's really small change (but error won't ever happen here) but it's ok
| } | ||
| if err := tx.Delete([]byte(hashKeyPrefix+s.Hash), nil); err != nil { | ||
| return err | ||
| if s.Sid != "" { |
There was a problem hiding this comment.
Sid should never be "" in the database. Services without Sid should be rejected as it is a mandatory data (at least if we have volumes)
There was a problem hiding this comment.
So they are not mandatory right now (they are marked as optional).
There was a problem hiding this comment.
What about volumes ? 2 services with no sid will share the same volume.
Right now they are not mandatory in the mesg.yml but generated with a value by default (_HASH if i remember correctly) so the definition file is optional but in the core mandatory.
This change related to Sid breaks volumes for services
There was a problem hiding this comment.
In service manager, if sid is empty it uses the hash.
The behavior is exactly like before.
There was a problem hiding this comment.
great I didn't see that. Also behavior is not exactly, we are taking the hash, before we where appending an character in front of the hash to make sure that we cannot create a service with the hash of another one as sid and then overwrite the previous service/volume. But anyway that was not a strong security anyway.
I still feel more confident to make sure that we can rely on a service to have a sid (that is generate when we deploy it like the hash) instead of having to check all the time we want to use the sid. I'm not necessary against it either it's just something I would like to have agreement to see the pro and con on that and not change something that impact the data.
There was a problem hiding this comment.
In that case, we have to generate different sid because one we generated one is an invalid domain. Also, sid should be used only for local development and should not be mandatory.
There was a problem hiding this comment.
sid is the base for the markeplace too so it's not only about local development. We put sid as optional with generation in order not to break previous services but every services needs to have a sid to identify this service and "group" the different version to the same service.
How do you manage services without sid on the marketplace for example ?
| return nil, err | ||
| } | ||
| // New creates an event eventKey with eventData for given service. | ||
| func New(s *service.Service, eventKey string, eventData map[string]interface{}) *Event { |
There was a problem hiding this comment.
Any good reason to move the validation from this package ? It ensure consistency in the data. Agree that it doesn't impact the data but in that case maybe the data should change and instead have a reference of the event maybe.
There was a problem hiding this comment.
It was moved to api package (so api handles all validation) and in that case event and execution packages depend only on service structure (and not the way how to validate them). So both package can take care only of it's logic (like update complete status for execution)
There was a problem hiding this comment.
I saw that this was moved on the API but what happen if we use the event/execution packages directly without the API ? We might introduce invalid data ? Also this doesn't reduce any dependencies as event/execution packages already depends on the service package.
| if err := task.RequireInputs(inputs); err != nil { | ||
| return nil, err | ||
| } | ||
| func New(service *service.Service, eventID string, taskKey string, inputs map[string]interface{}, tags []string) *Execution { |
| string image = 1; // Image's name of the container. | ||
| repeated string volumes = 2; // List of volumes. | ||
| repeated string volumesfrom = 3; // List of volumes mounted from other dependencies. | ||
| repeated string volumesFrom = 3; // List of volumes mounted from other dependencies. |
There was a problem hiding this comment.
this is breaking change, not critical and i'm ok with it but just that everyone acknowledge this
There was a problem hiding this comment.
It's fine here. The mesg.yml still have the volumesfrom.
There was a problem hiding this comment.
And no, it's not a breaking change, gRPC uses the number (in this case 3) to decode the data. So this is compatible with previous version.
There was a problem hiding this comment.
We are changing the data so it is a breaking change if any client like cli for example are reading this property which is quite unlikely but still this is a breaking change
| } | ||
|
|
||
| // Delete see Manager.Delete. | ||
| func (m *ContainerManager) Delete(service *Service) error { |
There was a problem hiding this comment.
Maybe DeleteVolumes. This doesn't delete the service so that's confusing
There was a problem hiding this comment.
So this is the implementation of the Manager interface
// Delete deletes all persistent data used by service.
Delete(service *Service) errorSo for Container, it happens to delete volumes but for other deploy methods, it could be something else.
There was a problem hiding this comment.
Instead of having the stop and delete logic in API, it could be done at the service manager.
Stop is just stopping the service.
Delete: stop + delete persistent data.
There was a problem hiding this comment.
No, it's manager part to have deleted and stop function separated. so api (or any other packge) can use them, and there they should be splited.
* service.Service type is now logicless and its relationship with Docker Containers will be managed by any implementation of manager.Manager. * Manager is responsible for managing Docker Containers of MESG Services. it can be implemented for any container orchestration tool. right now, Docker Service is the only one we have. related to #799.
service.Service type is now logicless and its relationship with Docker Containers will be managed by any implementation of manager.Manager. Manager is responsible for managing Docker Containers of MESG Services. it can be implemented for any container orchestration tool. right now, Docker Service is the only one we have. * service: Service.GetDependency(), Service.Namespace() & Dependency.Namespace() made public. related to #799.
service.Service type is now logicless and its relationship with Docker Containers will be managed by any implementation of manager.Manager. Manager is responsible for managing Docker Containers of MESG Services. it can be implemented for any container orchestration tool. right now, Docker Service is the only one we have. * service: Service.GetDependency(), Service.Namespace() & Dependency.Namespace() are made public. related to #799.
service.Service type is now logicless and its relationship with Docker Containers will be managed by any implementation of manager.Manager. Manager is responsible for managing Docker Containers of MESG Services. it can be implemented for any container orchestration tool. right now, Docker Service is the only one we have. * service: Service.GetDependency(), Service.Namespace() & Dependency.Namespace() func are made public. related to #799.
service.Service type is now logicless and its relationship with Docker Containers will be managed by any implementation of manager.Manager. Manager is responsible for managing Docker Containers of MESG Services. it can be implemented for any container orchestration tool. right now, Docker Service is the only one we have. * service: Service.GetDependency(), Service.Namespace() & Dependency.Namespace() func are made public. related to #799.
service.Service type is now logicless and its relationship with Docker Containers will be managed by any implementation of manager.Manager. Manager is responsible for managing Docker Containers of MESG Services. it can be implemented for any container orchestration tool. right now, Docker Service is the only one we have. * service: Service.GetDependency(), Service.Namespace() & Dependency.Namespace() func are made public. related to #799.
service.Service type is now logicless and its relationship with Docker Containers will be managed by any implementation of manager.Manager. Manager is responsible for managing Docker Containers of MESG Services. it can be implemented for any container orchestration tool. right now, Docker Service is the only one we have. * new manager pkg put under service/manager. * new dockermanager pkg put under service/manager/dockermanager. its logic is consist of the code split from service pkg. * service: Service.GetDependency(), Service.Namespace() & Dependency.Namespace() func are made public. * rename Manager.DeleteVolumes() as Manager.Delete(). related to #799.
service.Service type is now logicless and its relationship with Docker Containers will be managed by any implementation of manager.Manager. Manager is responsible for managing Docker Containers of MESG Services. it can be implemented for any container orchestration tool. right now, Docker Service is the only one we have. * new manager pkg put under service/manager. * new dockermanager pkg put under service/manager/dockermanager. its logic is consist of the code split from service pkg. * service: Service.GetDependency(), Service.Namespace() & Dependency.Namespace() funcs are made public. * service/manager: rename/have Manager.DeleteVolumes() as Manager.Delete(). related to #799.
|
Closing this PR as it's not relevant anymore |
No description provided.