Skip to content

Commit

Permalink
Protocol v1.0 (#306)
Browse files Browse the repository at this point in the history
* Drop plain-text compatibility support
* Bump min supported proto version to 0.13
* Support protocol v0.14
* Bump to proto v1.0 and preserve legacy proto
* Drop stmt_name of Parse
* Drop stmt_name of Execute
* Drop Execute and use OptimisticExecute instead
  • Loading branch information
fantix authored May 11, 2022
1 parent 9081105 commit 51344fe
Show file tree
Hide file tree
Showing 13 changed files with 612 additions and 245 deletions.
16 changes: 3 additions & 13 deletions edgedb/asyncio_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@


import asyncio
import functools
import logging
import socket
import ssl
Expand Down Expand Up @@ -62,10 +61,8 @@ async def connect_addr(self, addr, timeout):
async def sleep(self, seconds):
await asyncio.sleep(seconds)

def _protocol_factory(self, tls_compat=False):
return asyncio_proto.AsyncIOProtocol(
self._params, self._loop, tls_compat=tls_compat
)
def _protocol_factory(self):
return asyncio_proto.AsyncIOProtocol(self._params, self._loop)

async def _connect_addr(self, addr):
tr = None
Expand All @@ -84,14 +81,7 @@ async def _connect_addr(self, addr):
except ssl.CertificateError as e:
raise con_utils.wrap_error(e) from e
except ssl.SSLError as e:
if e.reason == 'CERTIFICATE_VERIFY_FAILED':
raise con_utils.wrap_error(e) from e
tr, pr = await self._loop.create_connection(
functools.partial(
self._protocol_factory, tls_compat=True
),
*addr,
)
raise con_utils.wrap_error(e) from e
else:
con_utils.check_alpn_protocol(
tr.get_extra_info('ssl_object')
Expand Down
6 changes: 5 additions & 1 deletion edgedb/base_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -196,7 +196,11 @@ async def raw_query(self, query_context: abstract.QueryContext):
try:
if reconnect:
await self.connect(single_attempt=True)
return await self._protocol.execute_anonymous(
if self._protocol.is_legacy:
execute = self._protocol.legacy_execute_anonymous
else:
execute = self._protocol.execute_anonymous
return await execute(
query=query_context.query.query,
args=query_context.query.args,
kwargs=query_context.query.kwargs,
Expand Down
18 changes: 2 additions & 16 deletions edgedb/blocking_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@ class BlockingIOConnection(base_client.BaseConnection):

async def connect_addr(self, addr, timeout):
deadline = time.monotonic() + timeout
tls_compat = False

if isinstance(addr, str):
# UNIX socket
Expand Down Expand Up @@ -69,18 +68,7 @@ async def connect_addr(self, addr, timeout):
except ssl.CertificateError as e:
raise con_utils.wrap_error(e) from e
except ssl.SSLError as e:
if e.reason == 'CERTIFICATE_VERIFY_FAILED':
raise con_utils.wrap_error(e) from e

# Retry in plain text
time_left = deadline - time.monotonic()
if time_left <= 0:
raise TimeoutError
sock.close()
sock = socket.socket(socket.AF_INET)
sock.settimeout(time_left)
sock.connect(addr)
tls_compat = True
raise con_utils.wrap_error(e) from e
else:
con_utils.check_alpn_protocol(sock)
except socket.gaierror as e:
Expand All @@ -97,9 +85,7 @@ async def connect_addr(self, addr, timeout):
if not isinstance(addr, str):
sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)

proto = blocking_proto.BlockingIOProtocol(
self._params, sock, tls_compat
)
proto = blocking_proto.BlockingIOProtocol(self._params, sock)
proto.set_connection(self)

try:
Expand Down
2 changes: 1 addition & 1 deletion edgedb/protocol/asyncio_proto.pxd
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ from . cimport protocol
from edgedb.pgproto.debug cimport PG_DEBUG


cdef class AsyncIOProtocol(protocol.SansIOProtocol):
cdef class AsyncIOProtocol(protocol.SansIOProtocolBackwardsCompatible):

cdef:
object transport
Expand Down
6 changes: 3 additions & 3 deletions edgedb/protocol/asyncio_proto.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,10 @@ from edgedb.pgproto.pgproto cimport (
from . cimport protocol


cdef class AsyncIOProtocol(protocol.SansIOProtocol):
cdef class AsyncIOProtocol(protocol.SansIOProtocolBackwardsCompatible):

def __init__(self, con_params, loop, tls_compat=False):
protocol.SansIOProtocol.__init__(self, con_params, tls_compat)
def __init__(self, con_params, loop):
protocol.SansIOProtocolBackwardsCompatible.__init__(self, con_params)

self.loop = loop
self.transport = None
Expand Down
2 changes: 1 addition & 1 deletion edgedb/protocol/blocking_proto.pxd
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ from . cimport protocol
from edgedb.pgproto.debug cimport PG_DEBUG


cdef class BlockingIOProtocol(protocol.SansIOProtocol):
cdef class BlockingIOProtocol(protocol.SansIOProtocolBackwardsCompatible):

cdef:
readonly object sock
Expand Down
6 changes: 3 additions & 3 deletions edgedb/protocol/blocking_proto.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,10 @@ from . cimport protocol
DEF RECV_BUF = 65536


cdef class BlockingIOProtocol(protocol.SansIOProtocol):
cdef class BlockingIOProtocol(protocol.SansIOProtocolBackwardsCompatible):

def __init__(self, con_params, sock, tls_compat):
protocol.SansIOProtocol.__init__(self, con_params, tls_compat)
def __init__(self, con_params, sock):
protocol.SansIOProtocolBackwardsCompatible.__init__(self, con_params)
self.sock = sock

cpdef abort(self):
Expand Down
15 changes: 4 additions & 11 deletions edgedb/protocol/codecs/codecs.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -108,11 +108,8 @@ cdef class CodecsRegistry:
elif t == CTYPE_SHAPE:
els = <uint16_t>hton.unpack_int16(frb_read(spec, 2))
for i in range(els):
if protocol_version >= (0, 11):
frb_read(spec, 4) # flags
frb_read(spec, 1) # cardinality
else:
frb_read(spec, 1) # flags
frb_read(spec, 4) # flags
frb_read(spec, 1) # cardinality
str_len = hton.unpack_uint32(frb_read(spec, 4))
# read the <str> (`str_len` bytes) and <pos> (2 bytes)
frb_read(spec, str_len + 2)
Expand Down Expand Up @@ -174,12 +171,8 @@ cdef class CodecsRegistry:
flags = cpython.PyTuple_New(els)
cards = cpython.PyTuple_New(els)
for i in range(els):
if protocol_version >= (0, 11):
flag = hton.unpack_uint32(frb_read(spec, 4)) # flags
cardinality = <uint8_t>frb_read(spec, 1)[0]
else:
flag = <uint8_t>frb_read(spec, 1)[0] # flags
cardinality = 0
flag = hton.unpack_uint32(frb_read(spec, 4)) # flags
cardinality = <uint8_t>frb_read(spec, 1)[0]

str_len = hton.unpack_uint32(frb_read(spec, 4))
name = cpythonx.PyUnicode_FromStringAndSize(
Expand Down
9 changes: 5 additions & 4 deletions edgedb/protocol/consts.pxi
Original file line number Diff line number Diff line change
Expand Up @@ -60,10 +60,11 @@ DEF TRANS_STATUS_IDLE = b'I'
DEF TRANS_STATUS_INTRANS = b'T'
DEF TRANS_STATUS_ERROR = b'E'

DEF PROTO_VER_MAJOR = 0
DEF PROTO_VER_MINOR_MIN = 9
DEF PROTO_VER_MINOR = 13
DEF PROTO_VER_MIN_TLS = (0, 11)
DEF PROTO_VER_MAJOR = 1
DEF PROTO_VER_MINOR = 0

DEF LEGACY_PROTO_VER_MAJOR = 0
DEF LEGACY_PROTO_VER_MINOR_MIN = 13

DEF QUERY_OPT_IMPLICIT_LIMIT = 0xFF01
DEF QUERY_OPT_INLINE_TYPENAMES = 0xFF02
Expand Down
7 changes: 6 additions & 1 deletion edgedb/protocol/protocol.pxd
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,6 @@ cdef class SansIOProtocol:

object con
readonly object con_params
readonly bint tls_compat

object backend_secret

Expand All @@ -100,12 +99,15 @@ cdef class SansIOProtocol:
readonly bytes last_details
readonly tuple protocol_version

readonly bint is_legacy

cdef encode_args(self, BaseCodec in_dc, WriteBuffer buf, args, kwargs)

cdef parse_data_messages(self, BaseCodec out_dc, result)
cdef parse_sync_message(self)
cdef parse_command_complete_message(self)
cdef parse_describe_type_message(self, CodecsRegistry reg)
cdef parse_type_data(self, CodecsRegistry reg)
cdef _amend_parse_error(
self, exc, IoFormat io_format, bint expect_one, bint required_one)

Expand Down Expand Up @@ -135,3 +137,6 @@ cdef class SansIOProtocol:
)

cdef ensure_connected(self)


include "protocol_v0.pxd"
Loading

0 comments on commit 51344fe

Please sign in to comment.