Skip to content

Commit

Permalink
Merge pull request #7 from jtprogru/feature/time-sleep
Browse files Browse the repository at this point in the history
Add timeout
  • Loading branch information
jtprogru authored Dec 8, 2021
2 parents 04d1632 + 05a7280 commit abf1ead
Show file tree
Hide file tree
Showing 11 changed files with 106 additions and 44 deletions.
4 changes: 1 addition & 3 deletions .github/FUNDING.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,2 @@

github:
- jtprogru
- t0pep0
github: [ "jtprogru", "t0pep0" ]
5 changes: 3 additions & 2 deletions .github/RELEASE-TEMPLATE.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# Announcements
# Release name

* First announcement
- First feature
- Second feature
29 changes: 7 additions & 22 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
on:
push:
branches: [main]
workflow_run:
workflows: [ "GolangCI-lint" ]
branches: [ main ]
types:
- completed
pull_request:
branches: [main]

Expand All @@ -11,38 +14,20 @@ defaults:
shell: bash

jobs:
lint:
name: Lint files
runs-on: 'ubuntu-latest'
steps:
- uses: actions/[email protected]
- uses: actions/setup-go@v2
with:
go-version: '1.16.4'
- name: golangci-lint
uses: golangci/[email protected]
with:
version: latest

build:
name: Build binary
runs-on: 'ubuntu-latest'
needs: lint
strategy:
matrix:
goosarch:
- 'darwin/amd64'
- 'darwin/arm64'
- 'linux/386'
- 'linux/amd64'
- 'linux/arm'
- 'linux/arm64'
steps:
- name: Checkout code
uses: actions/[email protected]
- uses: actions/setup-go@v2
with:
go-version: '1.17.3'
go-version: '1.17'

- name: Get OS and arch info
run: |
Expand All @@ -63,6 +48,6 @@ jobs:
with:
body_path: ".github/RELEASE-TEMPLATE.md"
draft: true
files: ${{env.BINARY_NAME}}
files: ${{ env.BINARY_NAME }}
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
30 changes: 30 additions & 0 deletions .github/workflows/golangci-lint.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
on:
push:
paths:
- "go.sum"
- "go.mod"
- "**.go"
- ".github/workflows/golangci-lint.yml"
- ".golangci.yml"
pull_request:
paths:
- "go.sum"
- "go.mod"
- "**.go"
- ".github/workflows/golangci-lint.yml"
- ".golangci.yml"

name: GolangCI-lint

jobs:
golangci:
name: lint
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v2

- name: Lint
uses: golangci/golangci-lint-action@v2
with:
version: v1.42.0
7 changes: 5 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
# go-monkill

[![Go Reference](https://pkg.go.dev/badge/github.com/jtprogru/go-monkill.svg)](https://pkg.go.dev/github.com/jtprogru/go-monkill)
[![GolangCI-lint](https://github.com/jtprogru/go-monkill/actions/workflows/golangci-lint.yml/badge.svg)](https://github.com/jtprogru/go-monkill/actions/workflows/golangci-lint.yml)
[![build](https://github.com/jtprogru/go-monkill/actions/workflows/build.yml/badge.svg)](https://github.com/jtprogru/go-monkill/actions/workflows/build.yml)
[![publish](https://github.com/jtprogru/go-monkill/actions/workflows/publish.yml/badge.svg)](https://github.com/jtprogru/go-monkill/actions/workflows/publish.yml)
[![GitHub stars](https://img.shields.io/github/stars/jtprogru/go-monkill.svg)](https://github.com/jtprogru/go-monkill/stargazers)
[![GitHub issues](https://img.shields.io/github/issues-raw/jtprogru/go-monkill)](https://github.com/jtprogru/go-monkill/issues)
[![GitHub release (latest by date)](https://img.shields.io/github/v/release/jtprogru/go-monkill)](https://github.com/jtprogru/go-monkill/releases/latest)
![GitHub](https://img.shields.io/github/license/jtprogru/go-monkill)
![Linux](https://img.shields.io/badge/-Linux-grey?logo=linux)
[![Go report](https://goreportcard.com/badge/github.com/jtprogru/go-monkill)](https://goreportcard.com/report/github.com/jtprogru/go-monkill)
[![GitHub](https://img.shields.io/github/license/jtprogru/go-monkill)](LICENSE)
[![Linux](https://img.shields.io/badge/-Linux-grey?logo=linux)](https://en.wikipedia.org/wiki/Linux)
[![Donate](https://img.shields.io/badge/-Donate-yellow?logo=paypal)](https://paypal.me/jtprogru)
[![LoC](https://tokei.rs/b1/github/jtprogru/go-monkill)](https://github.com/jtprogru/go-monkill)

A very simple utility that allows you to run the desired command or script as soon as a certain process with a known PID completes correctly or with an error.

Expand Down
8 changes: 6 additions & 2 deletions cmd/root.go
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
// Package cmd contains all commands

package cmd

import (
"github.com/spf13/cobra"
)

const Version string = "v0.1.1"
// Version of release
const Version string = "v0.2.0"

// rootCmd represents the base command when called without any subcommands
// rootCmd – default root command
// rootCmd show help message
var rootCmd = &cobra.Command{
Use: "monkill",
Short: "Monkill for watching a process will finish or be killed",
Expand Down
4 changes: 3 additions & 1 deletion cmd/version.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
// Package cmd contains all commands

package cmd

import (
Expand All @@ -6,7 +8,7 @@ import (
"github.com/spf13/cobra"
)

// versionCmd represents the version command
// versionCmd – show current version of this package
var versionCmd = &cobra.Command{
Use: "version",
Short: "Print the version number of monkill",
Expand Down
40 changes: 32 additions & 8 deletions cmd/watch.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
// Package cmd contains all commands

package cmd

import (
Expand All @@ -9,51 +11,73 @@ import (
"github.com/spf13/cobra"
)

// watchCmd represents the watch command
// watchCmd – run watch func
//
var watchCmd = &cobra.Command{
Use: "watch",
Short: "A brief description of your command",
Long: `Monitor when process with PID will killed or stopped and run what you need.
For example:
go-monkill watch --pid=12345 --command="ping jtprog.ru -c 4""
go-monkill watch --pid 12345 --command "ping jtprog.ru -c 4"
`,
RunE: func(cmd *cobra.Command, args []string) error {
l := zerolog.New(os.Stderr)
return watcher(WatcherConfig.pid, WatcherConfig.command, waiter.Waiter{}, executor.Executor{}, l)
l.Level(zerolog.TraceLevel)
return watcher(WatcherConfig.pid, WatcherConfig.command, WatcherConfig.timeout, waiter.Waiter{}, executor.Executor{}, l)
},
}

// Verbose flag
//var Verbose bool

// defaultPid is -1 for
var defaultPid int = -1

// defaultTimeOut is 250 milliseconds
var defaultTimeOut int64 = 250

// WatcherConfig provides config for watcher
var WatcherConfig struct {
pid int // Specified PID for process
command string // Specified command for running
timeout int64 // Specified timeout for sleep
}

// Add command watchCmd to rootCmd
//
// &WatcherConfig pid as PID for monitoring – defined in flag --pid
// &WatcherConfig command as command for running - defined in flag --command
// &WatcherConfig timeout as timeout for check process - defined in flag --timeout
func init() {
rootCmd.AddCommand(watchCmd)
watchCmd.PersistentFlags().IntVar(&WatcherConfig.pid, "pid", -1, "PID for watching")
// TODO: Implement verbose log output by flag --verbose
// rootCmd.InheritedFlags().BoolVar(&Verbose, "verbose", false, "Enable debug logging")
// TODO: Implement output to logfile by flag --logfile
// rootCmd.InheritedFlags().StringVar(&WatcherConfig.logfile, "logfile", "/tmp/go-monkill.log", "Enable debug logging")
watchCmd.PersistentFlags().IntVar(&WatcherConfig.pid, "pid", defaultPid, "PID for watching")
watchCmd.PersistentFlags().StringVar(&WatcherConfig.command, "command", "ping jtprog.ru -c 2", "Command for running")
watchCmd.PersistentFlags().Int64Var(&WatcherConfig.timeout, "timeout", defaultTimeOut, "Set timeout for check status of process")
}

// Waiter interface
// Waiter interface for monitor process PID every timeout milliseconds
type Waiter interface {
Wait(pid int) (<-chan struct{}, error)
Wait(pid int, timeout int64) (<-chan struct{}, error)
}

// Executor interface
type Executor interface {
Exec(command string) error
}

func watcher(pid int, command string, w Waiter, e Executor, l zerolog.Logger) error {
// watcher – run Waiter.Wait
// &WatcherConfig pid as PID for monitoring – defined in flag --pid
// &WatcherConfig command as command for running - defined in flag --command
// &WatcherConfig timeout as timeout for watch - defined in flag --timeout
func watcher(pid int, command string, timeout int64, w Waiter, e Executor, l zerolog.Logger) error {
l.Info().Int("pid", pid).Str("command", command).Msg("Arguments readed")
ch, err := w.Wait(pid)
ch, err := w.Wait(pid, timeout)
if err != nil {
l.Error().Err(err).Msg("Break execution. Error on watch process")
return err
Expand Down
8 changes: 8 additions & 0 deletions main.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
// Package go-monkill
// A very simple utility that allows you to run the desired command or script
// as soon as a certain process with a known PID completes correctly or with an error.
//
// For example:
//
// go-monkill watch --pid 12345 --command "ping jtprog.ru -c 4"

package main

import "github.com/jtprogru/go-monkill/cmd"
Expand Down
3 changes: 2 additions & 1 deletion pkg/executor/executor.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ import (
// Executor struct
type Executor struct{}

// Exec for running Executor with command
// Exec - running Executor with command (i.e.: "ping jtprog.ru -c 4" )
// TODO: Implement verbose logging for output
func (e Executor) Exec(command string) error {
cmds := strings.Split(command, " ")
if len(cmds) == 0 {
Expand Down
12 changes: 9 additions & 3 deletions pkg/waiter/waiter.go
Original file line number Diff line number Diff line change
@@ -1,12 +1,17 @@
package waiter

import "github.com/mitchellh/go-ps"
import (
"github.com/mitchellh/go-ps"
"time"
)

// Waiter struct
type Waiter struct{}

// Wait monitor process with defined PID
func (w Waiter) Wait(pid int) (<-chan struct{}, error) {
// Wait find process with defined PID and wait for process will finish or be killed.
// Checking the liveliness of the process occurs with a timeout delay.
// The timeout is set in milliseconds.
func (w Waiter) Wait(pid int, timeout int64) (<-chan struct{}, error) {
_, err := ps.FindProcess(pid)
if err != nil {
return nil, err
Expand All @@ -17,6 +22,7 @@ func (w Waiter) Wait(pid int) (<-chan struct{}, error) {
if pc, _ := ps.FindProcess(pid); pc == nil {
out <- struct{}{}
}
time.Sleep(time.Duration(timeout) / time.Second)
}
}()
return out, nil
Expand Down

0 comments on commit abf1ead

Please sign in to comment.