これは私の存在の悩みです。 getEC2Metrics
はチャンネルに公開されているもののよう複数のプロデューサ(ゴルーチン付き)でセマフォを実装する
type ec2Params struct {
sess *session.Session
region string
}
type cloudwatchParams struct {
cl cloudwatch.CloudWatch
id string
metric string
region string
}
type request struct {
ec2Params
cloudwatchParams
}
// Control concurrency and sync
var maxRoutines = 128
var sem chan bool
var req chan request
func main() {
sem := make(chan bool, maxRoutines)
for i := 0; i < maxRoutines; i++ {
sem <- true
}
req := make(chan request)
go func() { // This is my the producer
for _, arn := range arns {
arnCreds := startSession(arn)
for _, region := range regions {
sess, err := session.NewSession(
&aws.Config{****})
if err != nil {
failOnError(err, "Can't assume role")
}
req <- request{ec2Params: ec2Params{ **** }}
}
}
}()
for f := range(req) {
<- sem
if (ec2Params{}) != f.ec2Params {
go getEC2Metrics(****)
} else {
// I should be excercising this line of code too,
// but I'm not :(
go getMetricFromCloudwatch(****)
}
sem <- true
}
}
getEC2Metrics
とgetCloudwatchMetrics
はasynchronically req
にデータを公開すべきである
func getMetricFromCloudwatch(cl cloudwatch.CloudWatch, id, metric, region string) {
// Magic
}
func getEC2Metrics(sess *session.Session, region string) {
ec := ec2.New(sess)
var ids []string
l, err := ec.DescribeInstances(&ec2.DescribeInstancesInput{})
if err != nil {
fmt.Println(err.Error())
} else {
for _, rsv := range l.Reservations {
for _, inst := range rsv.Instances {
ids = append(ids, *inst.InstanceId)
}
}
metrics := cfg.AWSMetric.Metric
if len(ids) >= 0 {
cl := cloudwatch.New(sess)
for _, id := range ids{
for _, metric := range metrics {
// For what I can tell, execution get stuck here
req <- request{ cloudwatchParams: ***** }}
}
}
}
}
}
両方main
で匿名プロデューサーとgetEC2Metrics
を実行するためにゴルーチンですが、今のところそれはそうです処理されません。 goroutineの中から私が出版を止める何かがあるように見えますが、何も見つかりませんでした。私はこれについてどうやって行かなければならないのか知りたいと思います(これは実際に動作するセマフォーです)。
実装のベースは、ここで見つけることができます:必死https://burke.libbey.me/conserving-file-descriptors-in-go/
セマフォを使用していないので、トークンを取り出してゴルーチンを取り出し、トークンを元に戻すだけです。ブロックしないでください。あなたはセマフォを "埋める"必要はなく、セマフォを取るためにトークンを送信し、それを解放するトークンを受け取ることができます) – JimB
あなたは完全に正しいです!私はそれを更新し、私はgetEC2Metrics関数へのチャネル参照を渡す必要があるという別の問題を発見した。何らかの理由でグローバル定義を使用することはできません。 –