Pre-requisites: Please make sure docker is installed on the target machine
- Clone Repository
- RUN
make
This will build the image and rundocker-compose up
- Application will be available on
localhost:8080
PS: If you are not running with docker, please copy the content of .envs/.env.example
into .envs/.env
and fill in the fields.
If the environment is an empty string (""
), the system will search for the env file in this location.
A solution to this can be to run the application with the environment variable specified. Eg:
ENVIRONMENT=demo SECTOR_ID=300 make start
Application was deployed to Google Cloud Run and it's available on
https://dns-a336s4xzcq-ez.a.run.app
as the base URL.
Sample Request
PS: SectorID
in this example is 1500
. However, feel free to change this and watch the result change accordingly.
curl --location --request POST 'https://dns-a336s4xzcq-ez.a.run.app/calculate' \
--header 'Content-Type: application/json' \
--data-raw '{
"x": "0",
"y": "0",
"z": "3",
"vel": "200"
}'
This should return:
{
"loc": 4700
}
To test the MomCorp response:
curl --location --request POST 'https://dns-a336s4xzcq-ez.a.run.app/calculate?resp=mom' \
--header 'Content-Type: application/json' \
--data-raw '{
"x": "0",
"y": "0",
"z": "3",
"vel": "200"
}'
The response should be:
{
"location": 4700
}
-
For instrumentation, I will monitor the requests/per minute, the
latency of the requsts and also watch out for any CPU spike.
My tool of choice here will be prometheus for exporting metrics and
grafana for visualization. -
Throttling will be useful because you want to make sure that there
is a cool down period between the requests that the drone sends,
and a single drone doesn't end up hugging the entire resource.
Hence it will make sense, based on the expectation to limit the
number of requests a drone can send at any given period, eg not
more that 50 request per second. -
To service several sectors at a time, the sectors ID can be kept in
a map and themaths
service can take in this sector ID to
perform it's calculation on the fly. Hence instead of passing the
sectorID when a new service is created, it can be passed across
directly to theCalculate
function. to now make it look like:
func (ms *MathService) Calculate(ctx context.Context, sectorID float64, req *Request) float64
or the Request
entity can be made to include the sectorID:
type Request struct {
CoordX string `json:"x"`
CoordY string `json:"y"`
CoordZ string `json:"z"`
Velocity string `json:"vel"`
}
and this will be populated before passing it on to the maths service.
thus making the calculation to be like:
req.CoordX*req.SectorID + req.CoordY* req.sectorID + req.CoordZ*req.sectorID + req.Velocity
- Two ways to accomplish this.
a. The response package will have a new struct called
MomCorpResponse
where the server determines the origin of the request or the type of response, if it'sbasic/mom
. The eitherresponses.Basic
is returned orresponse.MomCorp
will be returned. b. Instead of returning a response struct, a map is used. This way, we can dynamically set the key for the map and retain the value of the calculation. eg:
response:=make(map[string]float64)
result:=ms.Calculate(ctx, req) // result of the calculation
switch (responseType){
case mc: // mom-corp response
response["location"] = result
return
default: // drone response
response["loc"] = result
}
b, err:=json.Marshal(result) //we proceed to return result.
- Versioning is the solution here. We can have
v1
andv2
and either maintain the same calculation package or have a different
caluclation package. The handler can then pick whichever package it wants based on the version.
There is already an interfaceIMathService
and as long as the new
calculation package implements this, all should be fine.
We can also have a map of the different versions, eg:
version:=map[string]IMathService{
"v1":maths.V1Service{},
"v2":maths.V2Service{},
}
switch(req.Version) { //determine the version from the http-request
case "v1":
return version["v1"].Calculate(ctx, req)
case "v2":
return version["v2"].Calculate(ctx, req)
default:
return nil,"version not defined"
}
- By having separate controlled environment to test those changes before customers can even have any access.
Allowing for A/B Tests to also help with user feedback during release cycles.
The deployment for example can be triggered by a CI/CD option but releases should be more intentional. Hence the rolling-out can be phased, either via a blue-green release or canary release.