jackc / pgx

PostgreSQL driver and toolkit for Go

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Clone a backend message

krisdiano opened this issue · comments

Is your feature request related to a problem? Please describe.
I used the pgconn to handle low level libpq protocol in my projects which are stream replication proxy. I found that the lifespan of messages which were returned from Receive method is very short. I have to clone the backend messages and keep messages in memory to send in proper time. Now, for clone, I need type assert, encode, define a variable and decode.

Describe the solution you'd like

type BackendMessage interface {
    Message()
    Clone() BackendMessage()
    Backend()
}

or

type Message interface {
    Encode([]byte) []byte
    Decode([]byte) error
    Clone() Message
}

The Message interface are also be contained in FrontedMessage, but the source of FrontedMessage is determined by users, so I think the first method is more reasonable. The simeplest way of Clone:

func (src *CopyData) Clone() BackendMessage {
	var ret CopyData
	_ = ret.Decode(src.Encode(nil)[5:])
	return &ret
}

Describe alternatives you've considered
A clear and concise description of any alternative solutions or features you've considered.

Additional context
Add any other context or screenshots about the feature request here.

Overall idea of making it simple to clone a message seems reasonable. But I'm not sure of the proper interface.

Not sure I totally understood your reasoning for deciding between adding to Message or BackendMessage interface. But adding to either interface is slightly unfortunate. Technically, it would be a breaking change to add to an interface. But practically speaking I don't think it would break any existing code. 🤷

But it is a bit weird for a *CopyData.Clone() to return a BackendMessage instead of another *CopyData. Maybe a CopyBackendMessage function should be added instead for the generic case.