Skip to content
Snippets Groups Projects
Commit faaf9f73 authored by Hans Moog's avatar Hans Moog
Browse files

Feat: commit of initial packages

parent f9d47f24
No related branches found
No related tags found
No related merge requests found
package gracefulshutdown
// The maximum amount of time we wait for background processes to terminate. After that the process is killed.
const WAIT_TO_KILL_TIME_IN_SECONDS = 10
package gracefulshutdown
import (
"github.com/iotaledger/goshimmer/packages/daemon"
"github.com/iotaledger/goshimmer/packages/node"
"os"
"os/signal"
"strconv"
"syscall"
"time"
)
func run(plugin *node.Plugin) {
gracefulStop := make(chan os.Signal)
signal.Notify(gracefulStop, syscall.SIGTERM)
signal.Notify(gracefulStop, syscall.SIGINT)
go func() {
<- gracefulStop
plugin.LogWarning("Received shutdown request - waiting (max " + strconv.Itoa(WAIT_TO_KILL_TIME_IN_SECONDS) + " seconds) to finish processing ...")
go func() {
start := time.Now()
for x := range time.Tick(1 * time.Second) {
secondsSinceStart := x.Sub(start).Seconds()
if secondsSinceStart <= WAIT_TO_KILL_TIME_IN_SECONDS {
plugin.LogWarning("Received shutdown request - waiting (max " + strconv.Itoa(WAIT_TO_KILL_TIME_IN_SECONDS - int(secondsSinceStart)) + " seconds) to finish processing ...")
} else {
plugin.LogFailure("The background processes did not terminate in time! Forcing shutdown ...")
os.Exit(1)
}
}
}()
daemon.Shutdown()
}()
}
var PLUGIN = node.NewPlugin("Graceful Shutdown", run)
package statusscreen
import "time"
const (
REPAINT_INTERVAL = 500 * time.Millisecond
)
package statusscreen
import (
"github.com/iotaledger/goshimmer/packages/node"
"time"
)
func storeStatusMessage(pluginName string, message string, logLevel int) {
messageLog = append(messageLog, &StatusMessage{
Source: pluginName,
LogLevel: logLevel,
Message: message,
Time: time.Now(),
})
if statusMessage, exists := statusMessages[pluginName]; !exists {
statusMessages[pluginName] = &StatusMessage{
Source: pluginName,
LogLevel: logLevel,
Message: message,
Time: time.Now(),
}
} else {
statusMessage.LogLevel = logLevel
statusMessage.Message = message
statusMessage.Time = time.Now()
}
}
var DEFAULT_LOGGER = &node.Logger{
Enabled: true,
LogInfo: func(pluginName string, message string) {
storeStatusMessage(pluginName, message, node.LOG_LEVEL_INFO)
},
LogSuccess: func(pluginName string, message string) {
storeStatusMessage(pluginName, message, node.LOG_LEVEL_SUCCESS)
},
LogWarning: func(pluginName string, message string) {
storeStatusMessage(pluginName, message, node.LOG_LEVEL_WARNING)
},
LogFailure: func(pluginName string, message string) {
storeStatusMessage(pluginName, message, node.LOG_LEVEL_FAILURE)
},
}
package statusscreen
import "time"
type StatusMessage struct {
Source string
LogLevel int
Message string
Time time.Time
}
package statusscreen
import (
"github.com/gdamore/tcell"
"github.com/iotaledger/goshimmer/packages/daemon"
"github.com/iotaledger/goshimmer/packages/node"
"github.com/rivo/tview"
"time"
)
var statusMessages = make(map[string]*StatusMessage)
var messageLog = make([]*StatusMessage, 0)
var app *tview.Application
func configure(plugin *node.Plugin) {
node.DEFAULT_LOGGER.Enabled = false
plugin.Node.AddLogger(DEFAULT_LOGGER)
daemon.Events.Shutdown.Attach(func() {
node.DEFAULT_LOGGER.Enabled = true
if app != nil {
app.Stop()
}
})
}
func run(plugin *node.Plugin) {
newPrimitive := func(text string) *tview.TextView {
textView := tview.NewTextView()
textView.
SetTextAlign(tview.AlignLeft).
SetText(" " + text)
return textView
}
app = tview.NewApplication()
headerBar := NewUIHeaderBar()
content := tview.NewGrid()
content.SetBackgroundColor(tcell.ColorWhite)
content.SetColumns(0)
footer := newPrimitive("")
footer.SetBackgroundColor(tcell.ColorDarkMagenta)
footer.SetTextColor(tcell.ColorWhite)
grid := tview.NewGrid().
SetRows(10, 0, 1).
SetColumns(0).
SetBorders(false).
AddItem(headerBar.Primitive, 0, 0, 1, 1, 0, 0, false).
AddItem(content, 1, 0, 1, 1, 0, 0, false).
AddItem(footer, 2, 0, 1, 1, 0, 0, false)
frame := tview.NewFrame(grid).
SetBorders(1, 1, 0, 0, 2, 2)
frame.SetBackgroundColor(tcell.ColorDarkGray)
app.SetInputCapture(func(event *tcell.EventKey) *tcell.EventKey {
if event.Key() == tcell.KeyCtrlC || event.Key() == tcell.KeyESC{
daemon.Shutdown()
return nil
}
return event
})
app.SetBeforeDrawFunc(func(screen tcell.Screen) bool {
headerBar.Update()
rows := make([]int, 1)
rows[0] = 1
_, _, _, height := content.GetRect()
for i := 0; i < len(messageLog) && i < height - 2; i++ {
rows = append(rows, 1)
}
content.Clear()
content.SetRows(rows...)
blankLine := newPrimitive("")
blankLine.SetBackgroundColor(tcell.ColorWhite)
content.AddItem(blankLine, 0, 0, 1, 1, 0, 0, false)
for i, message := range messageLog[len(messageLog) - len(rows) - 1 + 2:] {
if i < height - 2 {
content.AddItem(NewUILogEntry(*message).Primitive, i+1, 0, 1, 1, 0, 0, false)
}
}
return false
})
daemon.BackgroundWorker(func() {
for {
select {
case <- daemon.ShutdownSignal:
return
case <- time.After(1 * time.Second):
app.QueueUpdateDraw(func() {})
}
}
})
daemon.BackgroundWorker(func() {
if err := app.SetRoot(frame, true).SetFocus(frame).Run(); err != nil {
panic(err)
}
})
}
var PLUGIN = node.NewPlugin("Status Screen", configure, run)
package statusscreen
import (
"fmt"
"github.com/gdamore/tcell"
"github.com/iotaledger/goshimmer/packages/accountability"
"github.com/iotaledger/goshimmer/plugins/autopeering/peermanager"
"github.com/rivo/tview"
"strconv"
"time"
)
var start = time.Now()
type UIHeaderBar struct {
Primitive *tview.Grid
LogoContainer *tview.TextView
InfoContainer *tview.TextView
}
func NewUIHeaderBar() *UIHeaderBar {
headerBar := &UIHeaderBar{
Primitive: tview.NewGrid(),
LogoContainer: tview.NewTextView(),
InfoContainer: tview.NewTextView(),
}
headerBar.LogoContainer.
SetTextAlign(tview.AlignLeft).
SetTextColor(tcell.ColorWhite).
SetDynamicColors(true).
SetBackgroundColor(tcell.ColorDarkMagenta)
headerBar.InfoContainer.
SetTextAlign(tview.AlignRight).
SetTextColor(tcell.ColorWhite).
SetDynamicColors(true).
SetBackgroundColor(tcell.ColorDarkMagenta)
headerBar.Primitive.
SetColumns(17, 0).
SetRows(0).
SetBorders(false).
AddItem(headerBar.LogoContainer, 0, 0, 1, 1, 0, 0, false).
AddItem(headerBar.InfoContainer, 0, 1, 1, 1, 0, 0, false)
headerBar.printLogo()
headerBar.Update()
return headerBar
}
func (headerBar *UIHeaderBar) Update() {
duration := time.Now().Sub(start)
headerBar.InfoContainer.Clear()
fmt.Fprintln(headerBar.InfoContainer)
fmt.Fprintln(headerBar.InfoContainer, "[::d]COO-LESS IOTA PROTOTYPE - [::b]Status: [green::b]SYNCED ")
fmt.Fprintln(headerBar.InfoContainer)
fmt.Fprintln(headerBar.InfoContainer)
fmt.Fprintln(headerBar.InfoContainer)
fmt.Fprintln(headerBar.InfoContainer)
fmt.Fprintln(headerBar.InfoContainer, "[::b]Node Identifier: [::d]" + accountability.OWN_ID.StringIdentifier + " ")
fmt.Fprintln(headerBar.InfoContainer, "[::b]Known Peers: [::d]" + strconv.Itoa(len(peermanager.KNOWN_PEERS.Peers)) + " ")
fmt.Fprintf(headerBar.InfoContainer, "[::b]Uptime: [::d]");
if int(duration.Seconds()) / (60 * 60 * 24) > 0 {
// d
fmt.Fprintf(headerBar.InfoContainer, "%02dd ", int(duration.Hours()) / 24)
}
if int(duration.Seconds()) / (60 * 60) > 0 {
fmt.Fprintf(headerBar.InfoContainer, "%02dh ", int(duration.Hours()) % 24)
}
if int(duration.Seconds()) / 60 > 0 {
fmt.Fprintf(headerBar.InfoContainer, "%02dm ", int(duration.Minutes()) % 60)
}
fmt.Fprintf(headerBar.InfoContainer, "%02ds ", int(duration.Seconds()) % 60)
}
func (headerBar *UIHeaderBar) printLogo() {
fmt.Fprintln(headerBar.LogoContainer, "")
fmt.Fprintln(headerBar.LogoContainer, " SHIMMER 1.0.0")
fmt.Fprintln(headerBar.LogoContainer, " ┏━━━━━━┳━━━━━━┓")
fmt.Fprintln(headerBar.LogoContainer, " ━━━┓ ┃ ┏━━━")
fmt.Fprintln(headerBar.LogoContainer, " ┓ ┃ ┃ ┃ ┏")
fmt.Fprintln(headerBar.LogoContainer, " ┃ ┗ ┃ ┛ ┃")
fmt.Fprintln(headerBar.LogoContainer, " ┗ ┏ ┃ ┓ ┛")
fmt.Fprintln(headerBar.LogoContainer, " ┃ ┃ ┃")
fmt.Fprintln(headerBar.LogoContainer, " ┻")
}
package statusscreen
import "github.com/rivo/tview"
type UILog struct {
Primitive *tview.Grid
}
func NewUILog() *UILog {
uiLog := &UILog{
Primitive: tview.NewGrid(),
}
return uiLog
}
package statusscreen
import (
"fmt"
"github.com/gdamore/tcell"
"github.com/iotaledger/goshimmer/packages/node"
"github.com/rivo/tview"
)
type UILogEntry struct {
Primitive *tview.Grid
TimeContainer *tview.TextView
MessageContainer *tview.TextView
LogLevelContainer *tview.TextView
}
func NewUILogEntry(message StatusMessage) *UILogEntry {
logEntry := &UILogEntry{
Primitive: tview.NewGrid(),
TimeContainer: tview.NewTextView(),
MessageContainer: tview.NewTextView(),
LogLevelContainer: tview.NewTextView(),
}
logEntry.TimeContainer.SetBackgroundColor(tcell.ColorWhite)
logEntry.TimeContainer.SetTextColor(tcell.ColorBlack)
logEntry.TimeContainer.SetDynamicColors(true)
logEntry.MessageContainer.SetBackgroundColor(tcell.ColorWhite)
logEntry.MessageContainer.SetTextColor(tcell.ColorBlack)
logEntry.MessageContainer.SetDynamicColors(true)
logEntry.LogLevelContainer.SetBackgroundColor(tcell.ColorWhite)
logEntry.LogLevelContainer.SetTextColor(tcell.ColorBlack)
logEntry.LogLevelContainer.SetDynamicColors(true)
textColor := "black"
switch message.LogLevel {
case node.LOG_LEVEL_INFO:
fmt.Fprintf(logEntry.LogLevelContainer, " [black::d][ [blue::d]INFO [black::d]]")
case node.LOG_LEVEL_SUCCESS:
fmt.Fprintf(logEntry.LogLevelContainer, " [black::d][ [green::d]OK [black::d]]")
case node.LOG_LEVEL_WARNING:
fmt.Fprintf(logEntry.LogLevelContainer, " [black::d][ [yellow::d]WARN [black::d]]")
textColor = "yellow"
case node.LOG_LEVEL_FAILURE:
fmt.Fprintf(logEntry.LogLevelContainer, " [black::d][ [red::d]FAIL [black::d]]")
textColor = "red"
}
fmt.Fprintf(logEntry.TimeContainer, " [black::b]" + message.Time.Format("01/02/2006 03:04:05 PM"))
if message.Source == "Node" {
fmt.Fprintf(logEntry.MessageContainer, "[" + textColor + "::d]" + message.Message)
} else {
fmt.Fprintf(logEntry.MessageContainer, "[" + textColor + "::d]" + message.Source + ": " + message.Message)
}
logEntry.Primitive.
SetColumns(25, 0, 11).
SetRows(1).
SetBorders(false).
AddItem(logEntry.TimeContainer, 0, 0, 1, 1, 0, 0, false).
AddItem(logEntry.MessageContainer, 0, 1, 1, 1, 0, 0, false).
AddItem(logEntry.LogLevelContainer, 0, 2, 1, 1, 0, 0, false)
return logEntry
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment