tedsuo / ifrit Goto Github PK
View Code? Open in Web Editor NEWa simple process model for go
License: MIT License
a simple process model for go
License: MIT License
I'd love to use ifrit more in some of our code but I have no idea if I'm using it properly! Could you add some small documentation of the basics?
Thanks!
Its been a while since there was any activity on this project but us in the cf autoscaler project are looking to either move away from ifrit or enhance this because we are seeing some stalls in our shutdowns (and this is quite old). I was looking at the shutdown code for the http server and its got some complexity, which was needed to be back in the day.
We now have the server.shutdown()
(2017) function which does a proper gracefull shutdown. I would suggest we use this and a context timeout with a forced .close() if it times out, which would simplify it considerably (no need to keep track of connections).
Thoughts ?
Plus its time to have a mod file and a release versioning to keep up with the go environment.
Oh BTW the tests didnt pass last time I tried running them :/.
There is a http_server
package but not https_server
or similar.
steal https://github.com/concourse/testflight/blob/wip/runner/runner.go and make it better plz kthx
Seems kind of silly that this code is living in locket:
https://github.com/cloudfoundry/locket/blob/master/grpcserver/server.go
Seems like we should have generic grpc support in ifrit just like we have http support. Let us know if you agree and we might maybe cook up a PR.
Given that the Ginkgomon Runner doesn't expose its session, the only way to assert on its streams seems to be with Buffer()
. But since gexec.Session
s only expose s.Out
, how are you supposed to assert on s.Err
?
I'd be happy to make a PR, but was curious to know if I was just missing something here, or if you had an opinion about what the right abstraction would be.
As title ,
I want to know what license it is.
Could you please post a license file into the repo?
Thanks a lot.
ginkgomon
currently uses the StartCheck
string to check the readiness of the process it is monitoring, however for some classes of processes it would be useful to have a readiness check that does not rely on log lines.
Would you be amenable to a change that introduces a StartCheckFunc
or some other generalized readiness check the user can specify to determine readiness?
Some open questions/ideas about solutions that are worth discussing:
StartCheck
?
Hi @tedsuo,
First of all, I want to thank you for this library. I was looking for something like this and stumbled upon it.
While testing if the library suits my use case, I think I've found a bug or at least an unexpected behavior.
Let me share a sample of code that demonstrates it:
package main
import (
"fmt"
"github.com/tedsuo/ifrit"
"github.com/tedsuo/ifrit/grouper"
"github.com/tedsuo/ifrit/sigmon"
"log"
"os"
"syscall"
"time"
)
func main() {
log.Print("start")
duration, _ := time.ParseDuration("10s")
runner := &sleepRunner{duration: duration}
group := grouper.NewParallel(nil, grouper.Members{
{
Name: "sleeper",
Runner: runner,
},
})
rc := <-ifrit.Invoke(sigmon.New(group, syscall.SIGUSR1)).Wait()
log.Print("finish: ", rc)
}
type sleepRunner struct {
duration time.Duration
}
func (r *sleepRunner) Run(signals <-chan os.Signal, ready chan<- struct{}) error {
close(ready)
wake := time.Tick(r.duration)
log.Print("sleepRunner started")
for {
select {
case sig := <-signals:
log.Print("got signal: ", sig)
if sig == os.Interrupt {
return fmt.Errorf("interrupted")
}
case <-wake:
log.Print("sleepRunner finished")
return nil
}
}
}
If I run this code in a shell, and start sending USR1
signal to the process, the process ends:
$ go run main.go
2019/08/17 21:10:00 start
2019/08/17 21:10:00 sleepRunner started
2019/08/17 21:10:04 got signal: user defined signal 1
2019/08/17 21:10:05 got signal: user defined signal 1
2019/08/17 21:10:05 finish: <nil> # Notice, the process died after 5 seconds. If I don't send signals, it holds for 10 seconds, as required by duration.
# while this process is running I send signal USR1 from the separate shell like this:
$ pkill -USR1 main
$ pkill -USR1 main
...
No matter what signal I set to be propagated via sigmon
(I tried USR1
, USR2
, URG
), parallel grouper always dies on the second signal.
I'm pretty sure the bug is somewhere in grouper
package, because if I run runner
instead of group
, like rc := <-ifrit.Invoke(sigmon.New(runner, syscall.SIGUSR1)).Wait()
, it doesn't die after the second signal.
PS.
Update: I'm using go version go1.12.7 darwin/amd64
heyo @tedsuo - hope you are well! Are you still maintaining ifrit these days? A few CF folks are running into issues trying to upgrade to Ginkgo V2 and using the ginkgomon
helper that depends on Ginkgo V1. Would you be up for me submitting a PR that adds a ginkgomon_v2
package that depends on Ginkgo V2 instead to unblock folks?
I can also upgrade all the things to Ginkgo v2 if you'd like - but can just keep it simple and focused on the new package instead.
Thanks!
The design of Ifrit makes a great deal of sense for the general case of folks on POSIX-y operating systems.
On Windows, however, os.Signal
is not so much a thing -- os.Interrupt
exists, but as far as I can tell it's specific to applications running in a terminal session.
Perhaps a future version of the API should have more flexibility in the channel used to trigger graceful shutdown?
Ifrit currently does not have a version number, but let's call the current head of master v1.0.0
for the purpose of this PR. There are a set of changes – which I never got around to making while at Pivotal – which I feel could clean up the boilerplate code in main()
functions that use ifrit. This code is usuallly copy/pasted around, but it may improve on-boarding and comprehension to clean it up.
grouper
and sigmon
packages into the main ifrit
package. the additional package names create confusion when reading code, and they are almost always used together.ifrit.Main
method which wraps up the most common setup for ifrit into a single function.nil
members.ifrit.EventListener
interface (at least for use in ifrit.Main
), which allows logging boilerplate to be shared.Example of the above changes being applied:
https://gist.github.com/tedsuo/1e99de0d465330526ff2
Personally, I find the end result to be much more readable.
By porting the new functionality to the main package, ifrit could remain backwards compatible simply by leaving the current packages alone.
@nimakaviani @jvshahid @emalm since y’all make the heaviest use of ifrit, let me know if this of interest.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.