Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add goroutines #4

Merged
merged 3 commits into from
Oct 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
123 changes: 114 additions & 9 deletions coverage/coverage.html
Original file line number Diff line number Diff line change
Expand Up @@ -144,33 +144,87 @@
<pre class="file" id="file2" style="display: none">package domain_service

import (
"sync"

domain_model "github.com/mmadariaga/go-api/internal/domain/model"
)

type GetDriversByRaceDependencies interface {
FetchDriversByRace(raceId int) ([]domain_model.Driver, error)
}

type fetchDriversResponse struct {
raceId int
response []domain_model.Driver
error error
}

func GetDriversByRace(races []domain_model.Race, dependencies GetDriversByRaceDependencies) (map[int][]domain_model.Driver, error) <span class="cov8" title="1">{

driversByRace := make(map[int][]domain_model.Driver)

var waitGroup sync.WaitGroup
respChannel := make(chan fetchDriversResponse, 8)

for _, race := range races </span><span class="cov8" title="1">{
result, error := dependencies.FetchDriversByRace(race.Id)
if error != nil </span><span class="cov8" title="1">{
return nil, error
waitGroup.Add(1)
go fetchDrivers(
race.Id,
dependencies,
respChannel,
&amp;waitGroup,
)
}</span>

<span class="cov8" title="1">go func() </span><span class="cov8" title="1">{
waitGroup.Wait()
close(respChannel)
}</span>()

<span class="cov8" title="1">for resp := range respChannel </span><span class="cov8" title="1">{

if resp.error != nil </span><span class="cov8" title="1">{
return nil, resp.error
}</span>

<span class="cov8" title="1">driversByRace[race.Id] = result</span>
<span class="cov8" title="1">driversByRace[resp.raceId] = resp.response</span>
}

<span class="cov8" title="1">return driversByRace, nil</span>
}

func fetchDrivers(
raceId int,
dependencies GetDriversByRaceDependencies,
respChan chan&lt;- fetchDriversResponse,
waitGroup *sync.WaitGroup,
) <span class="cov8" title="1">{
defer waitGroup.Done()

result, error := dependencies.FetchDriversByRace(raceId)

if error != nil </span><span class="cov8" title="1">{
respChan &lt;- fetchDriversResponse{
raceId: raceId,
response: nil,
error: error,
}
return
}</span>

<span class="cov8" title="1">respChan &lt;- fetchDriversResponse{
raceId: raceId,
response: result,
error: nil,
}</span>
}
</pre>

<pre class="file" id="file3" style="display: none">package domain_service

import (
"sync"

domain_model "github.com/mmadariaga/go-api/internal/domain/model"
)

Expand All @@ -179,6 +233,12 @@
FetchPodiumByRace(raceId int, drivers []domain_model.Driver) ([3]domain_model.Podium, error)
}

type fetchPodiumsResponse struct {
raceId int
response [3]domain_model.Podium
error error
}

func GetPodiumByRace(
races []domain_model.Race,
dependencies GetPodiumByRaceDependencies,
Expand All @@ -191,17 +251,62 @@
return nil, error
}</span>

<span class="cov8" title="1">for _, race := range races </span><span class="cov8" title="1">{
result, error := dependencies.FetchPodiumByRace(race.Id, drivers[race.Id])
if error != nil </span><span class="cov8" title="1">{
return nil, error
<span class="cov8" title="1">var waitGroup sync.WaitGroup
respChannel := make(chan fetchPodiumsResponse, 8)
for _, race := range races </span><span class="cov8" title="1">{
waitGroup.Add(1)
go fetchPodiums(
race.Id,
drivers[race.Id],
dependencies,
respChannel,
&amp;waitGroup,
)
}</span>

<span class="cov8" title="1">go func() </span><span class="cov8" title="1">{
waitGroup.Wait()
close(respChannel)
}</span>()

<span class="cov8" title="1">for resp := range respChannel </span><span class="cov8" title="1">{

if resp.error != nil </span><span class="cov8" title="1">{
return nil, resp.error
}</span>

<span class="cov8" title="1">podiumsByRace[race.Id] = result</span>
<span class="cov8" title="1">podiumsByRace[resp.raceId] = resp.response</span>
}

<span class="cov8" title="1">return podiumsByRace, nil</span>
}

func fetchPodiums(
raceId int,
drivers []domain_model.Driver,
dependencies GetPodiumByRaceDependencies,
respChan chan&lt;- fetchPodiumsResponse,
waitGroup *sync.WaitGroup,
) <span class="cov8" title="1">{
defer waitGroup.Done()

result, error := dependencies.FetchPodiumByRace(raceId, drivers)

if error != nil </span><span class="cov8" title="1">{
respChan &lt;- fetchPodiumsResponse{
raceId: raceId,
response: [3]domain_model.Podium{},
error: error,
}
return
}</span>

<span class="cov8" title="1">respChan &lt;- fetchPodiumsResponse{
raceId: raceId,
response: result,
error: nil,
}</span>
}
</pre>

</div>
Expand Down
60 changes: 56 additions & 4 deletions internal/domain/service/GetDriversByRace.go
Original file line number Diff line number Diff line change
@@ -1,25 +1,77 @@
package domain_service

import (
"sync"

domain_model "github.com/mmadariaga/go-api/internal/domain/model"
)

type GetDriversByRaceDependencies interface {
FetchDriversByRace(raceId int) ([]domain_model.Driver, error)
}

type fetchDriversResponse struct {
raceId int
response []domain_model.Driver
error error
}

func GetDriversByRace(races []domain_model.Race, dependencies GetDriversByRaceDependencies) (map[int][]domain_model.Driver, error) {

driversByRace := make(map[int][]domain_model.Driver)

var waitGroup sync.WaitGroup
respChannel := make(chan fetchDriversResponse, 8)

for _, race := range races {
result, error := dependencies.FetchDriversByRace(race.Id)
if error != nil {
return nil, error
waitGroup.Add(1)
go fetchDrivers(
race.Id,
dependencies,
respChannel,
&waitGroup,
)
}

go func() {
waitGroup.Wait()
close(respChannel)
}()

for resp := range respChannel {

if resp.error != nil {
return nil, resp.error
}

driversByRace[race.Id] = result
driversByRace[resp.raceId] = resp.response
}

return driversByRace, nil
}

func fetchDrivers(
raceId int,
dependencies GetDriversByRaceDependencies,
respChan chan<- fetchDriversResponse,
waitGroup *sync.WaitGroup,
) {
defer waitGroup.Done()

result, error := dependencies.FetchDriversByRace(raceId)

if error != nil {
respChan <- fetchDriversResponse{
raceId: raceId,
response: nil,
error: error,
}
return
}

respChan <- fetchDriversResponse{
raceId: raceId,
response: result,
error: nil,
}
}
61 changes: 57 additions & 4 deletions internal/domain/service/GetPodiumByRace.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package domain_service

import (
"sync"

domain_model "github.com/mmadariaga/go-api/internal/domain/model"
)

Expand All @@ -9,6 +11,12 @@ type GetPodiumByRaceDependencies interface {
FetchPodiumByRace(raceId int, drivers []domain_model.Driver) ([3]domain_model.Podium, error)
}

type fetchPodiumsResponse struct {
raceId int
response [3]domain_model.Podium
error error
}

func GetPodiumByRace(
races []domain_model.Race,
dependencies GetPodiumByRaceDependencies,
Expand All @@ -21,14 +29,59 @@ func GetPodiumByRace(
return nil, error
}

var waitGroup sync.WaitGroup
respChannel := make(chan fetchPodiumsResponse, 8)
for _, race := range races {
result, error := dependencies.FetchPodiumByRace(race.Id, drivers[race.Id])
if error != nil {
return nil, error
waitGroup.Add(1)
go fetchPodiums(
race.Id,
drivers[race.Id],
dependencies,
respChannel,
&waitGroup,
)
}

go func() {
waitGroup.Wait()
close(respChannel)
}()

for resp := range respChannel {

if resp.error != nil {
return nil, resp.error
}

podiumsByRace[race.Id] = result
podiumsByRace[resp.raceId] = resp.response
}

return podiumsByRace, nil
}

func fetchPodiums(
raceId int,
drivers []domain_model.Driver,
dependencies GetPodiumByRaceDependencies,
respChan chan<- fetchPodiumsResponse,
waitGroup *sync.WaitGroup,
) {
defer waitGroup.Done()

result, error := dependencies.FetchPodiumByRace(raceId, drivers)

if error != nil {
respChan <- fetchPodiumsResponse{
raceId: raceId,
response: [3]domain_model.Podium{},
error: error,
}
return
}

respChan <- fetchPodiumsResponse{
raceId: raceId,
response: result,
error: nil,
}
}
5 changes: 4 additions & 1 deletion internal/infrastructure/service/FetchDriversByRace.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,10 @@ type Driver = domain_model.Driver
func FetchDriversByRace(raceId int) ([]Driver, error) {

targetUrl := "https://api.openf1.org/v1/drivers?session_key=" + strconv.Itoa(raceId)
body := helper.HttpGet(targetUrl, true)
body, err := helper.HttpGet(targetUrl, true)
if err != nil {
return nil, err
}

// JSON to struct
var drivers []struct {
Expand Down
5 changes: 4 additions & 1 deletion internal/infrastructure/service/FetchPodiumByRace.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,10 @@ type Position struct {
func FetchPodiumByRace(raceId int, drivers []domain_model.Driver) ([3]Podium, error) {

targetUrl := "https://api.openf1.org/v1/position?position<=3&session_key=" + strconv.Itoa(raceId)
body := helper.HttpGet(targetUrl, true)
body, err := helper.HttpGet(targetUrl, true)
if err != nil {
return [3]Podium{}, err
}

// JSON to struct
var positions []Position
Expand Down
5 changes: 4 additions & 1 deletion internal/infrastructure/service/FetchRacesByYear.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,10 @@ type Race = domain_model.Race
func FetchRacesByYear(year int) ([]Race, error) {

targetUrl := "https://api.openf1.org/v1/sessions?year=" + strconv.Itoa(year) + "&session_type=Race"
body := helper.HttpGet(targetUrl, true)
body, err := helper.HttpGet(targetUrl, true)
if err != nil {
return nil, err
}

// JSON to struct
var sessions []struct {
Expand Down
Loading
Loading