Created
January 5, 2024 08:49
-
-
Save wejick/99064411a9b671ffc3a8d96376835da5 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"sync" | |
"github.com/wejick/daging/repo/productcard" | |
"github.com/wejick/daging/repo/productinfo" | |
"github.com/wejick/daging/repo/productrating" | |
"github.com/wejick/daging/repo/shoprating" | |
) | |
// Define constants for each RPC call | |
const ( | |
productInfo = iota | |
productRating | |
sid | |
shopRating | |
productCard | |
) | |
func GetProductCard(productID PID, pc *productcard.ProductCard, pi *productinfo.ProductInfo, pr *productrating.ProductRating, sr *shoprating.ShopRating) productcard.ProductCard { | |
productInfoChan := make(chan productinfo.ProductInfo) | |
productRatingChan := make(chan productrating.ProductRating) | |
sidChan := make(chan SID) | |
shopRatingChan := make(chan shoprating.ShopRating) | |
productCardChan := make(chan productcard.ProductCard) | |
var productInfoResult productinfo.ProductInfo | |
var productRatingResult productrating.ProductRating | |
var sidResult SID | |
var shopRatingResult shoprating.ShopRating | |
var productCardResult productcard.ProductCard | |
var wg sync.WaitGroup | |
// Define the readiness map | |
ready := [5]bool{} | |
// Define the dependency matrix | |
matrix := map[int][]int{ | |
productInfo: {}, | |
productRating: {}, | |
sid: {productInfo}, | |
shopRating: {sid}, | |
productCard: {productInfo, productRating, shopRating}, | |
} | |
wg.Add(1) | |
// Start a goroutine for handling incoming data from channels | |
go func() { | |
continueLoop := true | |
for continueLoop { | |
select { | |
case productInfoResult = <-productInfoChan: | |
ready[productInfo] = true | |
case productRatingResult = <-productRatingChan: | |
ready[productRating] = true | |
case sidResult = <-sidChan: | |
ready[sid] = true | |
case shopRatingResult = <-shopRatingChan: | |
ready[shopRating] = true | |
case productCardResult = <-productCardChan: | |
ready[productCard] = true | |
continueLoop = false | |
} | |
} | |
}() | |
// Start a goroutine for running the RPC calls | |
go func() { | |
for { | |
doingWork := false | |
for rpc, deps := range matrix { | |
if !ready[rpc] { | |
doingWork = true | |
// Check if all dependencies have finished | |
allDepsReady := true | |
for _, dep := range deps { | |
if !ready[dep] { | |
allDepsReady = false | |
break | |
} | |
} | |
// If all dependencies have finished, start the RPC call | |
if allDepsReady { | |
switch rpc { | |
case productInfo: | |
go func() { | |
productInfoChan <- ProvideProductInfo(productID, pi) | |
}() | |
case productRating: | |
go func() { | |
productRatingChan <- ProvideProductRating(productID, pr) | |
}() | |
case sid: | |
go func() { | |
sidChan <- ProvideSID(productInfoResult) | |
}() | |
case shopRating: | |
go func() { | |
shopRatingChan <- ProvideShopRating(sidResult, sr) | |
}() | |
case productCard: | |
go func() { | |
productCardChan <- ProvideProductCard(productInfoResult, shopRatingResult, productRatingResult, pc) | |
}() | |
} | |
} | |
} | |
} | |
// all work has been done | |
if !doingWork { | |
wg.Done() | |
break | |
} | |
} | |
}() | |
wg.Wait() | |
return productCardResult | |
} | |
// wire.go: | |
type PID int | |
type SID int | |
func ProvideProductRating(productID PID, P *productrating.ProductRating) productrating.ProductRating { | |
return P.Call(int(productID)) | |
} | |
func ProvideProductInfo(productID PID, P *productinfo.ProductInfo) productinfo.ProductInfo { | |
return P.Call(int(productID)) | |
} | |
func ProvideShopRating(shopID SID, S *shoprating.ShopRating) shoprating.ShopRating { | |
return S.Call(int(shopID)) | |
} | |
func ProvideSID(productInfo productinfo.ProductInfo) SID { | |
return SID(productInfo.ShopID) | |
} | |
func ProvideProductCard(productInfo productinfo.ProductInfo, shopRating shoprating.ShopRating, | |
productRating productrating.ProductRating, P *productcard.ProductCard) productcard.ProductCard { | |
return P.Call(productcard.Param{ | |
ProductInfo: productInfo, | |
ShopRating: shopRating, | |
ProductRating: productRating, | |
}) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment