-
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fun/* additions, particularly either, promise and future
- Loading branch information
1 parent
6f93b4a
commit 1f48f70
Showing
14 changed files
with
694 additions
and
70 deletions.
There are no files selected for viewing
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,7 @@ | ||
github.com/tawesoft/golib | ||
|
||
Copyright © 2019 - 2022 Ben Golightly <[email protected]> | ||
Copyright © 2019 - 2022 Tawesoft Ltd <[email protected]> | ||
Copyright © 2019 - 2023 Ben Golightly <[email protected]> | ||
Copyright © 2019 - 2023 Tawesoft Ltd <[email protected]> | ||
Copyright © Contributors (api.github.com/repos/tawesoft/golib/contributors) | ||
Copyright © Unicode, W3C & others (some portions; see LICENSE-PARTS.txt) | ||
|
||
|
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
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,23 +1,27 @@ | ||
# Security Policy | ||
|
||
Contact: [[email protected]](mailto:[email protected]) | ||
[![Report A Vulnerability]](https://github.com/tawesoft/golib/security/advisories/new) | ||
[![View Security Advisories]](https://github.com/tawesoft/golib/security/advisories) | ||
|
||
Contact: [[email protected]](mailto:[email protected]) | ||
|
||
## Announcements | ||
|
||
It is our policy to publicly announce security issues and fixes through the | ||
GitHub "Security Advisories" feature for this repository. | ||
|
||
You can subscribe to security announcements for this repository by | ||
[configuring your "watching" settings](https://docs.github.com/en/account-and-profile/managing-subscriptions-and-notifications-on-github/setting-up-notifications/configuring-notifications#configuring-your-watch-settings-for-an-individual-repository) | ||
and subscribing to security alerts. | ||
To subscribe, [configure your watch settings] and tick either "All Activity" | ||
or select "custom" and tick "security alerts". | ||
|
||
[configure your watch settings]: (https://docs.github.com/en/account-and-profile/managing-subscriptions-and-notifications-on-github/setting-up-notifications/configuring-notifications#configuring-your-watch-settings-for-an-individual-repository) | ||
|
||
## Pre-announcements | ||
|
||
On a case-by-case basis, we are prepared to pre-announce security issues and | ||
fixes to any downstream consumer of this repository who can provide evidence | ||
that any security issues would have a particularly high impact on their | ||
services, such as operators of a service that processes personal data or is | ||
used by a large volume of users. Email us with the subject | ||
"join security-preannounce list" for details. | ||
services. Email [[email protected]](mailto:[email protected]) | ||
to discuss this. | ||
|
||
|
||
## Backporting fixes | ||
|
@@ -33,24 +37,23 @@ if necessary. | |
|
||
Please disclose responsibly so that we can notify the users of our software | ||
with a fix and/or instructions, including a pre-announcement where appropriate. | ||
Do not report security issues through the public issue tracker in the first | ||
instance, unless the vulnerability is being actively exploited in the wild or | ||
is already public knowledge. | ||
|
||
Instead, please email information about vulnerabilities to | ||
[[email protected]](mailto:[email protected]). | ||
**Please do not report security issues through the public issue tracker** in the | ||
first instance, unless the vulnerability is being actively exploited in the | ||
wild or is already public knowledge. Please use the option to securely | ||
report a vulnerability through GitHub at the top of this page. Alternatively, | ||
please email us at [[email protected]](mailto:[email protected]) | ||
and if necessary we can make other arrangements with you for secure disclosure. | ||
|
||
To help prioritise your report, format the subject line as follows: | ||
|
||
`vulnerability: repository-url - description` | ||
|
||
For example: | ||
If you don't receive an acknowledgement of your report within 48 hours, | ||
and you believe that urgent action is required, then please contact us through | ||
any contact method listed on the | ||
[Tawesoft website](https://www.tawesoft.co.uk/). | ||
|
||
`vulnerability: github.com/example/repo - denial of service in foo/bar` | ||
If we have not fixed or disclosed a vulnerability within 90 days of being | ||
notified, then we respect your right to disclose it publicly. | ||
|
||
If you don't receive an acknowledgement within 48 hours, please contact us | ||
through any contact method listed on the | ||
[Tawesoft website](https://www.tawesoft.co.uk/). | ||
|
||
If, after being notified, we have not fixed or disclosed a vulnerability after | ||
90 days, then you may exercise your right to disclose it publicly. | ||
<!--// button backgrounds //--> | ||
[Report A Vulnerability]: https://img.shields.io/badge/Report_A_Vulnerability-1f883d?style=for-the-badge&logo=github | ||
[View Security Advisories]: https://img.shields.io/badge/View_advisories-d86900?style=for-the-badge&logo=github |
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
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
// Package either implements a simple generic "Either" type that can represent | ||
// exactly one value out of two options. | ||
package either | ||
|
||
import ( | ||
"fmt" | ||
) | ||
|
||
// E represents a type that can hold either a value "a" of type A or a | ||
// value "b" of type B. | ||
type E[A any, B any] struct { | ||
a A | ||
b B | ||
index byte // 'a' or 'b' | ||
} | ||
|
||
// Pack returns an E that contains eotjer a value "a" of type A (if index == | ||
// 'a'), a value "b" of type B (if index == 'b'), or panics if index is not 'a' | ||
// or 'b'. | ||
func Pack[A any, B any](a A, b B, index byte) E[A, B] { | ||
if index == 'a' { | ||
return E[A, B]{a: a, index: index} | ||
} else if index == 'b' { | ||
return E[A, B]{b: b, index: index} | ||
} else { | ||
panic(fmt.Errorf("either: Pack[%T, %T](): invalid index value", a, b)) | ||
} | ||
} | ||
|
||
// Unpack returns the components of an E. The last return value is a | ||
// discriminator with the value 'a' or 'b' representing the existence of the | ||
// value "a" of type A or the value "b" of type B. | ||
func (e E[A, B]) Unpack() (A, B, byte) { | ||
return e.a, e.b, e.index | ||
} | ||
|
||
// A returns a new E that holds a value "a" of Type A. | ||
func A[A any, B any](a A) E[A, B] { | ||
return E[A, B]{ | ||
a: a, | ||
index: 'a', | ||
} | ||
} | ||
|
||
// B returns a new E that holds a value "b" of type B. | ||
func B[A any, B any](b B) E[A, B] { | ||
return E[A, B]{ | ||
b: b, | ||
index: 'b', | ||
} | ||
} | ||
|
||
// A returns the value "a" of type A and true if the E contains that value, | ||
// or the zero value and false otherwise. | ||
func (e E[A, B]) A() (result A, ok bool) { | ||
if e.index == 'a' { | ||
result = e.a | ||
ok = true | ||
} | ||
return | ||
} | ||
|
||
// B returns the value "b" of type B and true if the E contains that value, | ||
// or the zero value and false otherwise. | ||
func (e E[A, B]) B() (result B, ok bool) { | ||
if e.index == 'b' { | ||
result = e.b | ||
ok = true | ||
} | ||
return | ||
} |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
package future | ||
|
||
import ( | ||
"context" | ||
|
||
"github.com/tawesoft/golib/v2/fun/partial" | ||
"github.com/tawesoft/golib/v2/fun/promise" | ||
"github.com/tawesoft/golib/v2/fun/result" | ||
"github.com/tawesoft/golib/v2/fun/slices" | ||
) | ||
|
||
type async[T any] struct { | ||
context context.Context | ||
cancel context.CancelFunc | ||
channel chan result.R[T] | ||
} | ||
|
||
func start[T any](ctx context.Context, promise promise.P[T], channel chan result.R[T]) { | ||
value := result.New(promise.ComputeCtx(ctx)) | ||
for { | ||
select { | ||
case <- ctx.Done(): return | ||
default: channel <- value | ||
} | ||
} | ||
close(channel) | ||
} | ||
|
||
// NewAsync creates a new future from a promise, and begins computing that | ||
// promise asynchronously in a new goroutine. | ||
func NewAsync[T any](ctx context.Context, promise promise.P[T]) F[T] { | ||
ctxWithCancel, cancel := context.WithCancel(ctx) | ||
f := async[T]{ | ||
context: ctxWithCancel, | ||
cancel: cancel, | ||
channel: make(chan result.R[T]), | ||
} | ||
go start(ctxWithCancel, promise, f.channel) | ||
return f | ||
} | ||
|
||
// NewAsyncs is like [NewAsync], but accepts a slice of promises and returns a | ||
// slice of futures. | ||
func NewAsyncs[T any](ctx context.Context, xs []promise.P[T]) []F[T] { | ||
return slices.Map( | ||
partial.Left2(NewAsync[T])(ctx), | ||
xs, | ||
) | ||
} | ||
|
||
func (f async[T]) Collect() (result T, err error) { | ||
return f.CollectCtx(context.TODO()) | ||
} | ||
|
||
func (f async[T]) CollectCtx(ctx context.Context) (result T, err error) { | ||
select { | ||
case <- ctx.Done(): | ||
err = ctx.Err() | ||
return | ||
case <- f.context.Done(): | ||
err = f.context.Err() | ||
return | ||
case r := <- f.channel: | ||
result, err = r.Unpack() | ||
return | ||
} | ||
} | ||
|
||
func (f async[T]) Stop() { | ||
f.cancel() | ||
} | ||
|
||
func (f async[T]) Peek() (result T, err error) { | ||
select { | ||
case <- f.context.Done(): | ||
err = f.context.Err() | ||
return | ||
case r := <- f.channel: | ||
result, err = r.Unpack() | ||
return | ||
default: | ||
err = NotReady | ||
return | ||
} | ||
} |
Oops, something went wrong.