-
Notifications
You must be signed in to change notification settings - Fork 389
/
future.go
69 lines (61 loc) · 1.86 KB
/
future.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package pool
import (
"context"
"sync/atomic"
"time"
"github.com/pkg/errors"
)
//go:generate go run ../../tools/plc4xgenerator/gen.go -type=future
type future struct {
cancelRequested atomic.Bool
interruptRequested atomic.Bool
completed atomic.Bool
errored atomic.Bool
err atomic.Value
}
func (f *future) Cancel(interrupt bool, err error) {
f.cancelRequested.Store(true)
f.interruptRequested.Store(interrupt)
if err != nil {
f.errored.Store(true)
f.err.Store(err)
}
}
func (f *future) complete() {
f.completed.Store(true)
}
// Canceled is returned on CompletionFuture.AwaitCompletion when a CompletionFuture was canceled
var Canceled = errors.New("Canceled")
func (f *future) AwaitCompletion(ctx context.Context) error {
for !f.completed.Load() && !f.errored.Load() && !f.cancelRequested.Load() && ctx.Err() == nil {
time.Sleep(10 * time.Millisecond)
}
if err := ctx.Err(); err != nil {
return err
}
if err, ok := f.err.Load().(error); ok {
return err
}
if f.cancelRequested.Load() {
return Canceled
}
return nil
}