Skip to content

Commit 8959680

Browse files
committed
gocql: drop-in gocql replacement
1 parent 379fa26 commit 8959680

18 files changed

+6046
-0
lines changed

gocql/cluster.go

Lines changed: 268 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,268 @@
1+
package gocql
2+
3+
import (
4+
"log"
5+
"time"
6+
7+
"github.com/scylladb/scylla-go-driver"
8+
scyllalog "github.com/scylladb/scylla-go-driver/log"
9+
"github.com/scylladb/scylla-go-driver/transport"
10+
)
11+
12+
type ClusterConfig struct {
13+
// addresses for the initial connections. It is recommended to use the value set in
14+
// the Cassandra config for broadcast_address or listen_address, an IP address not
15+
// a domain name. This is because events from Cassandra will use the configured IP
16+
// address, which is used to index connected hosts. If the domain name specified
17+
// resolves to more than 1 IP address then the driver may connect multiple times to
18+
// the same host, and will not mark the node being down or up from events.
19+
Hosts []string
20+
21+
// CQL version (default: 3.0.0)
22+
CQLVersion string
23+
24+
// ProtoVersion sets the version of the native protocol to use, this will
25+
// enable features in the driver for specific protocol versions, generally this
26+
// should be set to a known version (2,3,4) for the cluster being connected to.
27+
//
28+
// If it is 0 or unset (the default) then the driver will attempt to discover the
29+
// highest supported protocol for the cluster. In clusters with nodes of different
30+
// versions the protocol selected is not defined (ie, it can be any of the supported in the cluster)
31+
ProtoVersion int
32+
33+
// Connection timeout (default: 600ms)
34+
Timeout time.Duration
35+
36+
// Initial connection timeout, used during initial dial to server (default: 600ms)
37+
// ConnectTimeout is used to set up the default dialer and is ignored if Dialer or HostDialer is provided.
38+
ConnectTimeout time.Duration
39+
40+
// Port used when dialing.
41+
// Default: 9042
42+
Port int
43+
44+
// Initial keyspace. Optional.
45+
Keyspace string
46+
47+
// Number of connections per host.
48+
// Default: 2
49+
NumConns int
50+
51+
// Default consistency level.
52+
// Default: Quorum
53+
Consistency Consistency
54+
55+
// Compression algorithm.
56+
// Default: nil
57+
Compressor Compressor
58+
59+
// Default: nil
60+
Authenticator Authenticator
61+
62+
// An Authenticator factory. Can be used to create alternative authenticators.
63+
// Default: nil
64+
// AuthProvider func(h *HostInfo) (Authenticator, error)
65+
66+
// Default retry policy to use for queries.
67+
// Default: no retries.
68+
RetryPolicy RetryPolicy
69+
70+
// ConvictionPolicy decides whether to mark host as down based on the error and host info.
71+
// Default: SimpleConvictionPolicy
72+
ConvictionPolicy ConvictionPolicy // TODO: use it?
73+
74+
// Default reconnection policy to use for reconnecting before trying to mark host as down.
75+
// ReconnectionPolicy ReconnectionPolicy
76+
77+
// The keepalive period to use, enabled if > 0 (default: 0)
78+
// SocketKeepalive is used to set up the default dialer and is ignored if Dialer or HostDialer is provided.
79+
SocketKeepalive time.Duration
80+
81+
// Maximum cache size for prepared statements globally for gocql.
82+
// Default: 1000
83+
MaxPreparedStmts int
84+
85+
// Maximum cache size for query info about statements for each session.
86+
// Default: 1000
87+
MaxRoutingKeyInfo int
88+
89+
// Default page size to use for created sessions.
90+
// Default: 5000
91+
PageSize int
92+
93+
// Consistency for the serial part of queries, values can be either SERIAL or LOCAL_SERIAL.
94+
// Default: unset
95+
// SerialConsistency SerialConsistency
96+
97+
// SslOpts configures TLS use when HostDialer is not set.
98+
// SslOpts is ignored if HostDialer is set.
99+
SslOpts *SslOptions
100+
101+
// Sends a client side timestamp for all requests which overrides the timestamp at which it arrives at the server.
102+
// Default: true, only enabled for protocol 3 and above.
103+
DefaultTimestamp bool
104+
105+
// PoolConfig configures the underlying connection pool, allowing the
106+
// configuration of host selection and connection selection policies.
107+
PoolConfig PoolConfig
108+
109+
// If not zero, gocql attempt to reconnect known DOWN nodes in every ReconnectInterval.
110+
ReconnectInterval time.Duration // FIXME: unused
111+
112+
// The maximum amount of time to wait for schema agreement in a cluster after
113+
// receiving a schema change frame. (default: 60s)
114+
MaxWaitSchemaAgreement time.Duration
115+
116+
// HostFilter will filter all incoming events for host, any which don't pass
117+
// the filter will be ignored. If set will take precedence over any options set
118+
// via Discovery
119+
// HostFilter HostFilter
120+
121+
// AddressTranslator will translate addresses found on peer discovery and/or
122+
// node change events.
123+
// AddressTranslator AddressTranslator
124+
125+
// If IgnorePeerAddr is true and the address in system.peers does not match
126+
// the supplied host by either initial hosts or discovered via events then the
127+
// host will be replaced with the supplied address.
128+
//
129+
// For example if an event comes in with host=10.0.0.1 but when looking up that
130+
// address in system.local or system.peers returns 127.0.0.1, the peer will be
131+
// set to 10.0.0.1 which is what will be used to connect to.
132+
IgnorePeerAddr bool
133+
134+
// If DisableInitialHostLookup then the driver will not attempt to get host info
135+
// from the system.peers table, this will mean that the driver will connect to
136+
// hosts supplied and will not attempt to lookup the hosts information, this will
137+
// mean that data_centre, rack and token information will not be available and as
138+
// such host filtering and token aware query routing will not be available.
139+
DisableInitialHostLookup bool
140+
141+
// Configure events the driver will register for
142+
Events struct {
143+
// disable registering for status events (node up/down)
144+
DisableNodeStatusEvents bool
145+
// disable registering for topology events (node added/removed/moved)
146+
DisableTopologyEvents bool
147+
// disable registering for schema events (keyspace/table/function removed/created/updated)
148+
DisableSchemaEvents bool
149+
}
150+
151+
// DisableSkipMetadata will override the internal result metadata cache so that the driver does not
152+
// send skip_metadata for queries, this means that the result will always contain
153+
// the metadata to parse the rows and will not reuse the metadata from the prepared
154+
// statement.
155+
//
156+
// See https://issues.apache.org/jira/browse/CASSANDRA-10786
157+
DisableSkipMetadata bool
158+
159+
// QueryObserver will set the provided query observer on all queries created from this session.
160+
// Use it to collect metrics / stats from queries by providing an implementation of QueryObserver.
161+
// QueryObserver QueryObserver
162+
163+
// BatchObserver will set the provided batch observer on all queries created from this session.
164+
// Use it to collect metrics / stats from batch queries by providing an implementation of BatchObserver.
165+
// BatchObserver BatchObserver
166+
167+
// ConnectObserver will set the provided connect observer on all queries
168+
// created from this session.
169+
// ConnectObserver ConnectObserver
170+
171+
// FrameHeaderObserver will set the provided frame header observer on all frames' headers created from this session.
172+
// Use it to collect metrics / stats from frames by providing an implementation of FrameHeaderObserver.
173+
// FrameHeaderObserver FrameHeaderObserver
174+
175+
// Default idempotence for queries
176+
DefaultIdempotence bool
177+
178+
// The time to wait for frames before flushing the frames connection to Cassandra.
179+
// Can help reduce syscall overhead by making less calls to write. Set to 0 to
180+
// disable.
181+
//
182+
// (default: 200 microseconds)
183+
WriteCoalesceWaitTime time.Duration
184+
185+
// Dialer will be used to establish all connections created for this Cluster.
186+
// If not provided, a default dialer configured with ConnectTimeout will be used.
187+
// Dialer is ignored if HostDialer is provided.
188+
// Dialer Dialer
189+
190+
// HostDialer will be used to establish all connections for this Cluster.
191+
// Unlike Dialer, HostDialer is responsible for setting up the entire connection, including the TLS session.
192+
// To support shard-aware port, HostDialer should implement ShardDialer.
193+
// If not provided, Dialer will be used instead.
194+
// HostDialer HostDialer
195+
196+
// DisableShardAwarePort will prevent the driver from connecting to Scylla's shard-aware port,
197+
// even if there are nodes in the cluster that support it.
198+
//
199+
// It is generally recommended to leave this option turned off because gocql can use
200+
// the shard-aware port to make the process of establishing more robust.
201+
// However, if you have a cluster with nodes which expose shard-aware port
202+
// but the port is unreachable due to network configuration issues, you can use
203+
// this option to work around the issue. Set it to true only if you neither can fix
204+
// your network nor disable shard-aware port on your nodes.
205+
DisableShardAwarePort bool
206+
207+
// Logger for this ClusterConfig.
208+
// If not specified, defaults to the global gocql.Logger.
209+
Logger StdLogger
210+
211+
// internal config for testing
212+
disableControlConn bool
213+
disableInit bool
214+
}
215+
216+
func NewCluster(hosts ...string) *ClusterConfig {
217+
cfg := ClusterConfig{Hosts: hosts, WriteCoalesceWaitTime: 200 * time.Microsecond}
218+
return &cfg
219+
}
220+
221+
func sessionConfigFromGocql(cfg *ClusterConfig) (scylla.SessionConfig, error) {
222+
scfg := scylla.DefaultSessionConfig(cfg.Keyspace, cfg.Hosts...)
223+
scfg.Hosts = cfg.Hosts
224+
scfg.WriteCoalesceWaitTime = cfg.WriteCoalesceWaitTime
225+
if _, ok := cfg.Compressor.(SnappyCompressor); ok {
226+
scfg.Compression = scylla.Snappy
227+
}
228+
229+
if auth, ok := cfg.Authenticator.(PasswordAuthenticator); ok {
230+
scfg.Username = auth.Username
231+
scfg.Password = auth.Password
232+
}
233+
234+
if policy, ok := cfg.PoolConfig.HostSelectionPolicy.(transport.HostSelectionPolicy); ok {
235+
scfg.HostSelectionPolicy = policy
236+
}
237+
238+
if retryPolicy, ok := cfg.RetryPolicy.(transport.RetryPolicy); ok {
239+
scfg.RetryPolicy = retryPolicy
240+
}
241+
242+
if cfg.Logger == nil {
243+
if Logger == nil {
244+
scfg.Logger = scyllalog.NewDefaultLogger()
245+
} else {
246+
scfg.Logger = stdLoggerWrapper{Logger}
247+
}
248+
} else {
249+
if cfg.Logger == nil {
250+
cfg.Logger = log.Default()
251+
}
252+
scfg.Logger = stdLoggerWrapper{cfg.Logger}
253+
}
254+
255+
if cfg.SslOpts != nil {
256+
tlsConfig, err := setupTLSConfig(cfg.SslOpts)
257+
if err != nil {
258+
return scylla.SessionConfig{}, err
259+
}
260+
scfg.TLSConfig = tlsConfig
261+
}
262+
263+
return scfg, nil
264+
}
265+
266+
func (cfg *ClusterConfig) CreateSession() (*Session, error) {
267+
return NewSession(*cfg)
268+
}

0 commit comments

Comments
 (0)