func (n *Network) Wait() {
	n.wg.Wait()
}
Wait until simulation finish
package ns_x
import (
	"github.com/bytedance/ns-x/v2/base"
	"github.com/bytedance/ns-x/v2/tick"
	"runtime"
	"sync"
	"time"
)
type Network struct {
	nodes  []base.Node
	buffer *base.EventBuffer
	wg     *sync.WaitGroup
}
func NewNetwork(nodes []base.Node) *Network {
	return &Network{
		nodes:  nodes,
		buffer: base.NewEventBuffer(),
		wg:     &sync.WaitGroup{},
	}
}
func (n *Network) eventLoop(eventQueue *base.EventQueue, clock tick.Clock, lifetime time.Duration) {
	runtime.LockOSThread()
	defer runtime.UnlockOSThread()
	defer n.wg.Done()
	now := clock()
	deadline := now.Add(lifetime)
	println("network main loop start at", now.String())
	for !now.After(deadline) && !eventQueue.IsEmpty() {
		p := eventQueue.Peek()
		t := p.Time()
		if t.After(now) {
			now = clock()
			continue
		}
		events := p.Action()(t)
		eventQueue.Dequeue()
		for _, event := range events {
			eventQueue.Enqueue(event)
		}
	}
	println("network main loop end at", now.String())
}
func (n *Network) Run(events []base.Event, clock tick.Clock, lifetime time.Duration, configs ...Config) {
	n.wg.Add(1)
	for _, node := range n.nodes {
		node.Check()
	}
	config := &config{
		bucketSize: DefaultBucketSize,
		maxBuckets: DefaultMaxBuckets,
	}
	config.apply(configs...)
	eventQueue := base.NewEventQueue(config.bucketSize, config.maxBuckets)
	for _, event := range events {
		eventQueue.Enqueue(event)
	}
	go n.eventLoop(eventQueue, clock, lifetime)
}