Browse Source

Merge pull request #1224 from slingamn/errors_again

minor refactoring
tags/v2.3.0-rc1
Shivaram Lingamneni 3 years ago
parent
commit
8f490ae298
No account linked to committer's email address
12 changed files with 60 additions and 52 deletions
  1. 9
    7
      irc/channelmanager.go
  2. 6
    5
      irc/channelreg.go
  3. 2
    2
      irc/client.go
  4. 3
    1
      irc/client_test.go
  5. 3
    3
      irc/config.go
  6. 0
    7
      irc/errors.go
  7. 3
    3
      irc/handlers.go
  8. 7
    2
      irc/ircconn.go
  9. 0
    11
      irc/types.go
  10. 6
    8
      irc/utils/semaphores.go
  11. 17
    0
      irc/utils/types.go
  12. 4
    3
      irc/znc.go

+ 9
- 7
irc/channelmanager.go View File

5
 
5
 
6
 import (
6
 import (
7
 	"sync"
7
 	"sync"
8
+
9
+	"github.com/oragono/oragono/irc/utils"
8
 )
10
 )
9
 
11
 
10
 type channelManagerEntry struct {
12
 type channelManagerEntry struct {
23
 	sync.RWMutex // tier 2
25
 	sync.RWMutex // tier 2
24
 	// chans is the main data structure, mapping casefolded name -> *Channel
26
 	// chans is the main data structure, mapping casefolded name -> *Channel
25
 	chans               map[string]*channelManagerEntry
27
 	chans               map[string]*channelManagerEntry
26
-	chansSkeletons      StringSet // skeletons of *unregistered* chans
27
-	registeredChannels  StringSet // casefolds of registered chans
28
-	registeredSkeletons StringSet // skeletons of registered chans
29
-	purgedChannels      StringSet // casefolds of purged chans
28
+	chansSkeletons      utils.StringSet // skeletons of *unregistered* chans
29
+	registeredChannels  utils.StringSet // casefolds of registered chans
30
+	registeredSkeletons utils.StringSet // skeletons of registered chans
31
+	purgedChannels      utils.StringSet // casefolds of purged chans
30
 	server              *Server
32
 	server              *Server
31
 }
33
 }
32
 
34
 
33
 // NewChannelManager returns a new ChannelManager.
35
 // NewChannelManager returns a new ChannelManager.
34
 func (cm *ChannelManager) Initialize(server *Server) {
36
 func (cm *ChannelManager) Initialize(server *Server) {
35
 	cm.chans = make(map[string]*channelManagerEntry)
37
 	cm.chans = make(map[string]*channelManagerEntry)
36
-	cm.chansSkeletons = make(StringSet)
38
+	cm.chansSkeletons = make(utils.StringSet)
37
 	cm.server = server
39
 	cm.server = server
38
 
40
 
39
 	cm.loadRegisteredChannels(server.Config())
41
 	cm.loadRegisteredChannels(server.Config())
47
 	}
49
 	}
48
 
50
 
49
 	rawNames := cm.server.channelRegistry.AllChannels()
51
 	rawNames := cm.server.channelRegistry.AllChannels()
50
-	registeredChannels := make(StringSet, len(rawNames))
51
-	registeredSkeletons := make(StringSet, len(rawNames))
52
+	registeredChannels := make(utils.StringSet, len(rawNames))
53
+	registeredSkeletons := make(utils.StringSet, len(rawNames))
52
 	for _, name := range rawNames {
54
 	for _, name := range rawNames {
53
 		cfname, err := CasefoldChannel(name)
55
 		cfname, err := CasefoldChannel(name)
54
 		if err == nil {
56
 		if err == nil {

+ 6
- 5
irc/channelreg.go View File

4
 package irc
4
 package irc
5
 
5
 
6
 import (
6
 import (
7
+	"encoding/json"
7
 	"fmt"
8
 	"fmt"
8
 	"strconv"
9
 	"strconv"
9
 	"strings"
10
 	"strings"
10
 	"time"
11
 	"time"
11
 
12
 
12
-	"encoding/json"
13
+	"github.com/tidwall/buntdb"
13
 
14
 
14
 	"github.com/oragono/oragono/irc/modes"
15
 	"github.com/oragono/oragono/irc/modes"
15
-	"github.com/tidwall/buntdb"
16
+	"github.com/oragono/oragono/irc/utils"
16
 )
17
 )
17
 
18
 
18
 // this is exclusively the *persistence* layer for channel registration;
19
 // this is exclusively the *persistence* layer for channel registration;
140
 }
141
 }
141
 
142
 
142
 // PurgedChannels returns the set of all casefolded channel names that have been purged
143
 // PurgedChannels returns the set of all casefolded channel names that have been purged
143
-func (reg *ChannelRegistry) PurgedChannels() (result map[string]empty) {
144
-	result = make(map[string]empty)
144
+func (reg *ChannelRegistry) PurgedChannels() (result utils.StringSet) {
145
+	result = make(utils.StringSet)
145
 
146
 
146
 	prefix := fmt.Sprintf(keyChannelPurged, "")
147
 	prefix := fmt.Sprintf(keyChannelPurged, "")
147
 	reg.server.store.View(func(tx *buntdb.Tx) error {
148
 	reg.server.store.View(func(tx *buntdb.Tx) error {
150
 				return false
151
 				return false
151
 			}
152
 			}
152
 			channel := strings.TrimPrefix(key, prefix)
153
 			channel := strings.TrimPrefix(key, prefix)
153
-			result[channel] = empty{}
154
+			result.Add(channel)
154
 			return true
155
 			return true
155
 		})
156
 		})
156
 	})
157
 	})

+ 2
- 2
irc/client.go View File

64
 	destroyed          bool
64
 	destroyed          bool
65
 	modes              modes.ModeSet
65
 	modes              modes.ModeSet
66
 	hostname           string
66
 	hostname           string
67
-	invitedTo          StringSet
67
+	invitedTo          utils.StringSet
68
 	isSTSOnly          bool
68
 	isSTSOnly          bool
69
 	languages          []string
69
 	languages          []string
70
 	lastActive         time.Time            // last time they sent a command that wasn't PONG or similar
70
 	lastActive         time.Time            // last time they sent a command that wasn't PONG or similar
1641
 	defer client.stateMutex.Unlock()
1641
 	defer client.stateMutex.Unlock()
1642
 
1642
 
1643
 	if client.invitedTo == nil {
1643
 	if client.invitedTo == nil {
1644
-		client.invitedTo = make(StringSet)
1644
+		client.invitedTo = make(utils.StringSet)
1645
 	}
1645
 	}
1646
 
1646
 
1647
 	client.invitedTo.Add(casefoldedChannel)
1647
 	client.invitedTo.Add(casefoldedChannel)

+ 3
- 1
irc/client_test.go View File

5
 
5
 
6
 import (
6
 import (
7
 	"testing"
7
 	"testing"
8
+
9
+	"github.com/oragono/oragono/irc/utils"
8
 )
10
 )
9
 
11
 
10
 func TestGenerateBatchID(t *testing.T) {
12
 func TestGenerateBatchID(t *testing.T) {
11
 	var session Session
13
 	var session Session
12
-	s := make(StringSet)
14
+	s := make(utils.StringSet)
13
 
15
 
14
 	count := 100000
16
 	count := 100000
15
 	for i := 0; i < count; i++ {
17
 	for i := 0; i < count; i++ {

+ 3
- 3
irc/config.go View File

624
 // OperClass defines an assembled operator class.
624
 // OperClass defines an assembled operator class.
625
 type OperClass struct {
625
 type OperClass struct {
626
 	Title        string
626
 	Title        string
627
-	WhoisLine    string    `yaml:"whois-line"`
628
-	Capabilities StringSet // map to make lookups much easier
627
+	WhoisLine    string          `yaml:"whois-line"`
628
+	Capabilities utils.StringSet // map to make lookups much easier
629
 }
629
 }
630
 
630
 
631
 // OperatorClasses returns a map of assembled operator classes from the given config.
631
 // OperatorClasses returns a map of assembled operator classes from the given config.
663
 
663
 
664
 			// create new operclass
664
 			// create new operclass
665
 			var oc OperClass
665
 			var oc OperClass
666
-			oc.Capabilities = make(StringSet)
666
+			oc.Capabilities = make(utils.StringSet)
667
 
667
 
668
 			// get inhereted info from other operclasses
668
 			// get inhereted info from other operclasses
669
 			if len(info.Extends) > 0 {
669
 			if len(info.Extends) > 0 {

+ 0
- 7
irc/errors.go View File

73
 	errRegisteredOnly                 = errors.New("Cannot join registered-only channel without an account")
73
 	errRegisteredOnly                 = errors.New("Cannot join registered-only channel without an account")
74
 )
74
 )
75
 
75
 
76
-// Socket Errors
77
-var (
78
-	errNoPeerCerts = errors.New("Client did not provide a certificate")
79
-	errNotTLS      = errors.New("Not a TLS connection")
80
-	errReadQ       = errors.New("ReadQ Exceeded")
81
-)
82
-
83
 // String Errors
76
 // String Errors
84
 var (
77
 var (
85
 	errCouldNotStabilize = errors.New("Could not stabilize string while casefolding")
78
 	errCouldNotStabilize = errors.New("Could not stabilize string while casefolding")

+ 3
- 3
irc/handlers.go View File

2998
 		}
2998
 		}
2999
 	} else {
2999
 	} else {
3000
 		// Construct set of channels the client is in.
3000
 		// Construct set of channels the client is in.
3001
-		userChannels := make(map[*Channel]bool)
3001
+		userChannels := make(ChannelSet)
3002
 		for _, channel := range client.Channels() {
3002
 		for _, channel := range client.Channels() {
3003
-			userChannels[channel] = true
3003
+			userChannels[channel] = empty{}
3004
 		}
3004
 		}
3005
 
3005
 
3006
 		// Another client is a friend if they share at least one channel, or they are the same client.
3006
 		// Another client is a friend if they share at least one channel, or they are the same client.
3010
 			}
3010
 			}
3011
 
3011
 
3012
 			for _, channel := range otherClient.Channels() {
3012
 			for _, channel := range otherClient.Channels() {
3013
-				if userChannels[channel] {
3013
+				if _, present := userChannels[channel]; present {
3014
 					return true
3014
 					return true
3015
 				}
3015
 				}
3016
 			}
3016
 			}

+ 7
- 2
irc/ircconn.go View File

3
 import (
3
 import (
4
 	"bufio"
4
 	"bufio"
5
 	"bytes"
5
 	"bytes"
6
+	"errors"
6
 	"net"
7
 	"net"
7
 	"unicode/utf8"
8
 	"unicode/utf8"
8
 
9
 
17
 )
18
 )
18
 
19
 
19
 var (
20
 var (
20
-	crlf = []byte{'\r', '\n'}
21
+	crlf     = []byte{'\r', '\n'}
22
+	errReadQ = errors.New("ReadQ Exceeded")
21
 )
23
 )
22
 
24
 
23
 // IRCConn abstracts away the distinction between a regular
25
 // IRCConn abstracts away the distinction between a regular
31
 	// these take an IRC line or lines, correctly terminated with CRLF:
33
 	// these take an IRC line or lines, correctly terminated with CRLF:
32
 	WriteLine([]byte) error
34
 	WriteLine([]byte) error
33
 	WriteLines([][]byte) error
35
 	WriteLines([][]byte) error
34
-	// this returns an IRC line without the terminating CRLF:
36
+	// this returns an IRC line, possibly terminated with CRLF, LF, or nothing:
35
 	ReadLine() (line []byte, err error)
37
 	ReadLine() (line []byte, err error)
36
 
38
 
37
 	Close() error
39
 	Close() error
127
 		messageType, line, err = wc.conn.ReadMessage()
129
 		messageType, line, err = wc.conn.ReadMessage()
128
 		// on empty message or non-text message, try again, block if necessary
130
 		// on empty message or non-text message, try again, block if necessary
129
 		if err != nil || (messageType == websocket.TextMessage && len(line) != 0) {
131
 		if err != nil || (messageType == websocket.TextMessage && len(line) != 0) {
132
+			if err == websocket.ErrReadLimit {
133
+				err = errReadQ
134
+			}
130
 			return
135
 			return
131
 		}
136
 		}
132
 	}
137
 	}

+ 0
- 11
irc/types.go View File

28
 	return ok
28
 	return ok
29
 }
29
 }
30
 
30
 
31
-type StringSet map[string]empty
32
-
33
-func (s StringSet) Has(str string) bool {
34
-	_, ok := s[str]
35
-	return ok
36
-}
37
-
38
-func (s StringSet) Add(str string) {
39
-	s[str] = empty{}
40
-}
41
-
42
 // MemberSet is a set of members with modes.
31
 // MemberSet is a set of members with modes.
43
 type MemberSet map[*Client]*modes.ModeSet
32
 type MemberSet map[*Client]*modes.ModeSet
44
 
33
 

+ 6
- 8
irc/utils/semaphores.go View File

10
 	"time"
10
 	"time"
11
 )
11
 )
12
 
12
 
13
-type e struct{}
14
-
15
 // Semaphore is a counting semaphore.
13
 // Semaphore is a counting semaphore.
16
 // A semaphore of capacity 1 can be used as a trylock.
14
 // A semaphore of capacity 1 can be used as a trylock.
17
-type Semaphore (chan e)
15
+type Semaphore (chan empty)
18
 
16
 
19
 // Initialize initializes a semaphore to a given capacity.
17
 // Initialize initializes a semaphore to a given capacity.
20
 func (semaphore *Semaphore) Initialize(capacity int) {
18
 func (semaphore *Semaphore) Initialize(capacity int) {
21
-	*semaphore = make(chan e, capacity)
19
+	*semaphore = make(chan empty, capacity)
22
 }
20
 }
23
 
21
 
24
 // Acquire acquires a semaphore, blocking if necessary.
22
 // Acquire acquires a semaphore, blocking if necessary.
25
 func (semaphore *Semaphore) Acquire() {
23
 func (semaphore *Semaphore) Acquire() {
26
-	(*semaphore) <- e{}
24
+	(*semaphore) <- empty{}
27
 }
25
 }
28
 
26
 
29
 // TryAcquire tries to acquire a semaphore, returning whether the acquire was
27
 // TryAcquire tries to acquire a semaphore, returning whether the acquire was
30
 // successful. It never blocks.
28
 // successful. It never blocks.
31
 func (semaphore *Semaphore) TryAcquire() (acquired bool) {
29
 func (semaphore *Semaphore) TryAcquire() (acquired bool) {
32
 	select {
30
 	select {
33
-	case (*semaphore) <- e{}:
31
+	case (*semaphore) <- empty{}:
34
 		return true
32
 		return true
35
 	default:
33
 	default:
36
 		return false
34
 		return false
47
 
45
 
48
 	timer := time.NewTimer(timeout)
46
 	timer := time.NewTimer(timeout)
49
 	select {
47
 	select {
50
-	case (*semaphore) <- e{}:
48
+	case (*semaphore) <- empty{}:
51
 		acquired = true
49
 		acquired = true
52
 	case <-timer.C:
50
 	case <-timer.C:
53
 		acquired = false
51
 		acquired = false
61
 // Note that if the context is already expired, the acquire may succeed anyway.
59
 // Note that if the context is already expired, the acquire may succeed anyway.
62
 func (semaphore *Semaphore) AcquireWithContext(ctx context.Context) (acquired bool) {
60
 func (semaphore *Semaphore) AcquireWithContext(ctx context.Context) (acquired bool) {
63
 	select {
61
 	select {
64
-	case (*semaphore) <- e{}:
62
+	case (*semaphore) <- empty{}:
65
 		acquired = true
63
 		acquired = true
66
 	case <-ctx.Done():
64
 	case <-ctx.Done():
67
 		acquired = false
65
 		acquired = false

+ 17
- 0
irc/utils/types.go View File

1
+// Copyright (c) 2020 Shivaram Lingamneni
2
+// released under the MIT license
3
+
4
+package utils
5
+
6
+type empty struct{}
7
+
8
+type StringSet map[string]empty
9
+
10
+func (s StringSet) Has(str string) bool {
11
+	_, ok := s[str]
12
+	return ok
13
+}
14
+
15
+func (s StringSet) Add(str string) {
16
+	s[str] = empty{}
17
+}

+ 4
- 3
irc/znc.go View File

10
 	"time"
10
 	"time"
11
 
11
 
12
 	"github.com/oragono/oragono/irc/history"
12
 	"github.com/oragono/oragono/irc/history"
13
+	"github.com/oragono/oragono/irc/utils"
13
 )
14
 )
14
 
15
 
15
 const (
16
 const (
62
 type zncPlaybackTimes struct {
63
 type zncPlaybackTimes struct {
63
 	start   time.Time
64
 	start   time.Time
64
 	end     time.Time
65
 	end     time.Time
65
-	targets StringSet // nil for "*" (everything), otherwise the channel names
66
+	targets utils.StringSet // nil for "*" (everything), otherwise the channel names
66
 	setAt   time.Time
67
 	setAt   time.Time
67
 }
68
 }
68
 
69
 
122
 		end = zncWireTimeToTime(params[3])
123
 		end = zncWireTimeToTime(params[3])
123
 	}
124
 	}
124
 
125
 
125
-	var targets StringSet
126
+	var targets utils.StringSet
126
 	var nickTargets []string
127
 	var nickTargets []string
127
 
128
 
128
 	// three cases:
129
 	// three cases:
145
 	if params[1] == "*" {
146
 	if params[1] == "*" {
146
 		playPrivmsgs = true // XXX nil `targets` means "every channel"
147
 		playPrivmsgs = true // XXX nil `targets` means "every channel"
147
 	} else {
148
 	} else {
148
-		targets = make(StringSet)
149
+		targets = make(utils.StringSet)
149
 		for _, targetName := range strings.Split(targetString, ",") {
150
 		for _, targetName := range strings.Split(targetString, ",") {
150
 			if targetName == "*self" {
151
 			if targetName == "*self" {
151
 				playPrivmsgs = true
152
 				playPrivmsgs = true

Loading…
Cancel
Save