Add "network delete" service command
And add all the infrastructure required to stop and delete networks. References: https://todo.sr.ht/~emersion/soju/17
This commit is contained in:
parent
1f11976e7a
commit
96039320b6
23
db.go
23
db.go
@ -215,6 +215,29 @@ func (db *DB) StoreNetwork(username string, network *Network) error {
|
||||
return err
|
||||
}
|
||||
|
||||
func (db *DB) DeleteNetwork(id int64) error {
|
||||
db.lock.Lock()
|
||||
defer db.lock.Unlock()
|
||||
|
||||
tx, err := db.db.Begin()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer tx.Rollback()
|
||||
|
||||
_, err = tx.Exec("DELETE FROM Network WHERE id = ?", id)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
_, err = tx.Exec("DELETE FROM Channel WHERE network = ?", id)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return tx.Commit()
|
||||
}
|
||||
|
||||
func (db *DB) ListChannels(networkID int64) ([]Channel, error) {
|
||||
db.lock.RLock()
|
||||
defer db.lock.RUnlock()
|
||||
|
32
service.go
32
service.go
@ -97,6 +97,11 @@ func init() {
|
||||
desc: "show a list of saved networks and their current status",
|
||||
handle: handleServiceNetworkStatus,
|
||||
},
|
||||
"delete": {
|
||||
usage: "<name>",
|
||||
desc: "delete a network",
|
||||
handle: handleServiceNetworkDelete,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
@ -143,9 +148,14 @@ func handleServiceHelp(dc *downstreamConn, params []string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func handleServiceCreateNetwork(dc *downstreamConn, params []string) error {
|
||||
func newFlagSet() *flag.FlagSet {
|
||||
fs := flag.NewFlagSet("", flag.ContinueOnError)
|
||||
fs.SetOutput(ioutil.Discard)
|
||||
return fs
|
||||
}
|
||||
|
||||
func handleServiceCreateNetwork(dc *downstreamConn, params []string) error {
|
||||
fs := newFlagSet()
|
||||
addr := fs.String("addr", "", "")
|
||||
name := fs.String("name", "", "")
|
||||
username := fs.String("username", "", "")
|
||||
@ -177,7 +187,7 @@ func handleServiceCreateNetwork(dc *downstreamConn, params []string) error {
|
||||
return fmt.Errorf("could not create network: %v", err)
|
||||
}
|
||||
|
||||
sendServicePRIVMSG(dc, fmt.Sprintf("created network %s successfully", network.GetName()))
|
||||
sendServicePRIVMSG(dc, fmt.Sprintf("created network %q", network.GetName()))
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -204,3 +214,21 @@ func handleServiceNetworkStatus(dc *downstreamConn, params []string) error {
|
||||
})
|
||||
return nil
|
||||
}
|
||||
|
||||
func handleServiceNetworkDelete(dc *downstreamConn, params []string) error {
|
||||
if len(params) != 1 {
|
||||
return fmt.Errorf("expected exactly one argument")
|
||||
}
|
||||
|
||||
net := dc.user.getNetwork(params[0])
|
||||
if net == nil {
|
||||
return fmt.Errorf("unknown network %q", params[0])
|
||||
}
|
||||
|
||||
if err := dc.user.deleteNetwork(net.ID); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
sendServicePRIVMSG(dc, fmt.Sprintf("deleted network %q", net.GetName()))
|
||||
return nil
|
||||
}
|
||||
|
50
user.go
50
user.go
@ -37,8 +37,9 @@ type eventDownstreamDisconnected struct {
|
||||
|
||||
type network struct {
|
||||
Network
|
||||
user *user
|
||||
ring *Ring
|
||||
user *user
|
||||
ring *Ring
|
||||
stopped chan struct{}
|
||||
|
||||
lock sync.Mutex
|
||||
conn *upstreamConn
|
||||
@ -50,6 +51,7 @@ func newNetwork(user *user, record *Network) *network {
|
||||
Network: *record,
|
||||
user: user,
|
||||
ring: NewRing(user.srv.RingCap),
|
||||
stopped: make(chan struct{}),
|
||||
history: make(map[string]uint64),
|
||||
}
|
||||
}
|
||||
@ -57,6 +59,13 @@ func newNetwork(user *user, record *Network) *network {
|
||||
func (net *network) run() {
|
||||
var lastTry time.Time
|
||||
for {
|
||||
select {
|
||||
case <-net.stopped:
|
||||
return
|
||||
default:
|
||||
// This space is intentionally left blank
|
||||
}
|
||||
|
||||
if dur := time.Now().Sub(lastTry); dur < retryConnectMinDelay {
|
||||
delay := retryConnectMinDelay - dur
|
||||
net.user.srv.Logger.Printf("waiting %v before trying to reconnect to %q", delay.Truncate(time.Second), net.Addr)
|
||||
@ -92,6 +101,19 @@ func (net *network) upstream() *upstreamConn {
|
||||
return net.conn
|
||||
}
|
||||
|
||||
func (net *network) Stop() {
|
||||
select {
|
||||
case <-net.stopped:
|
||||
return
|
||||
default:
|
||||
close(net.stopped)
|
||||
}
|
||||
|
||||
if uc := net.upstream(); uc != nil {
|
||||
uc.Close()
|
||||
}
|
||||
}
|
||||
|
||||
type user struct {
|
||||
User
|
||||
srv *Server
|
||||
@ -265,3 +287,27 @@ func (u *user) createNetwork(net *Network) (*network, error) {
|
||||
go network.run()
|
||||
return network, nil
|
||||
}
|
||||
|
||||
func (u *user) deleteNetwork(id int64) error {
|
||||
for i, net := range u.networks {
|
||||
if net.ID != id {
|
||||
continue
|
||||
}
|
||||
|
||||
if err := u.srv.db.DeleteNetwork(net.ID); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
u.forEachDownstream(func(dc *downstreamConn) {
|
||||
if dc.network != nil && dc.network == net {
|
||||
dc.Close()
|
||||
}
|
||||
})
|
||||
|
||||
net.Stop()
|
||||
u.networks = append(u.networks[:i], u.networks[i+1:]...)
|
||||
return nil
|
||||
}
|
||||
|
||||
panic("tried deleting a non-existing network")
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user