Обсуждение: Cheapest way to poll for notifications? & Driver improvement question re SSL and notify

Поиск
Список
Период
Сортировка

Cheapest way to poll for notifications? & Driver improvement question re SSL and notify

От
Craig Ringer
Дата:
Hi folks

Just to follow up on an earlier discussion on -general that turns out to
be JDBC-specific: it turns out that there _is_ a need to poll for
notifications using a dummy statement when a Java/JDBC client is using
an SSL socket.

The short version is that the JDBC driver can't check an SSL socket to
see if any data is availible for reading - the check always returns 0
due to a limitation in the underling SSLSocket provided by the JRE. So a
JDBC client using SSL must still send dummy statements to get notifications.

So my question is: is there any particularly low-overhead statement that
might be suitable for generating pointless client/server chat to check
for received async notifications? Should I just use "SELECT 1" ? Or
would I be better off using a SHOW statement like "SHOW role" to avoid
creating a snapshot etc?

I had a look at the v3 protocol documentatation and didn't see any sort
of "echo" or "ping"-type message that might be used to (a) test the
server for aliveness and (b) guarantee readable data of a known size on
the client's input stream. So the polling looks like it has to be done
at the SQL level not the protocol level.




=== alternative: blocking getNotifications() ===

An alternative is to provide an alternate form of getNotifications()
that can block. It'd be unsynchronized, being intended for a dedicated
thread in the app to use to poll for notifications. It'd call a blocking
equivalent to QueryExecutorImpl.processNotifies() ( let's call it
waitForNoitifies() ) that didn't check available() before attempting to
read from the input stream.

The problem here is that while PGStream.readChar() as called from
QueryExecutorImpl.waitForNotifies() was blocked waiting for input,
someone else in another thread might try to read from the PGStream while
doing normal work. PGStream would have to be able to block that read
until the readChar() from processNotifies() returned, AND would have to
be able to push the result of readChar() back onto the
VisibleBufferedInputStream used by PGStream if it wasn't an async
notification message.

I don't know how to do that without incurring plenty of nasty
synchronization overhead.

So, what I'm wondering is if it's worth having an alternative stream
class, say PGSynchronizedStream, that extends a PGStream with thread
safety. The driver user could, via the PGConnection interface, request
that blocking notification checking be enabled, causing the usual
PGStream to be replaced with PGSynchronizedStream. It would then be
possible to call something like getNotificationsBlocking() to trigger
QueryExecutorImpl.waitForNotifies() as described above.

The only other change needed to support this would be add a pushChar()
method to VisibleBufferedInputStream to permit input the blocking
notification checker read but didn't want to be pushed back into the
input stream.

This way, if you wanted async notifications over an SSL socket you'd
have to pay the price of some read-synchronization overhead in
PGSynchronizedStream, but otherwise not much would change anywhere in
the code.

Is this crazy? Is there something obvious I've missed?



=== Why can't JDBC/SSL just test for data ready to read, anyway? ===

The server can send async notifications over an SSL socket, no problem.
It generates an appropriate SSL message via the ssl library and sends it
down the wire.

A Java SSL client, though, cannot check to see if it can read from an
SSL socket without blocking. InputStream.available() always returns zero
on a Java SSL socket, because while there may be data in the underlying
connection buffer, the SSL client isn't sure if (a) it's a full SSL
message, and (b) if that message contains data for the client. It
doesn't seem to want to do the processing and buffering required to
figure that out in the available() call.

It's an annoying issue. In theory there's nothing that prevents
non-blocking I/O on SSL sockets - OpenSSL can do it, with a few quirks.
Java's SSLSocket can't do it, though. To get non-blocking SSL in Java
you apparently have to completely re-write your client using java.nio
async I/O and use the SSLEngine to do manual SSL handling on top of
that. There's no standard friendly-to-use non-blocking SSL socket
wrapper on top of that, and direct use of SSLEngine is ... "interesting".

There are 3rd party implementations of wrappers that make a java.nio &
SSLEngine-based system look like a normal SSLSocket, like ScalableSSL's
SSLSocketChannel. that brings behaviour much like OpenSSL's
almost-transparent non-blocking SSL - ie it looks like a normal
non-blocking socket except for a few quirks re handshaking.
SSLSocketChannel still doesn't do available() checking, though the docs
say it can be added.

Even if that was sorted out though, SSLEngine is also present only in
JDK 1.5 and above, so the JDBC driver can't use it for a while yet.



On 11/12/2009 11:39 PM, Craig Ringer wrote:
> Scott, Tom, Merlin:
>
> Thanks for the comments and help. It's all sorted now - the origin of
> the confusion was some outdated information in the JDBC driver
> documentation.
>
> The question arose because I was originally looking at polling from JDBC
> (which I know I forgot to mention), where the docs state that:
>
> "A key limitation of the JDBC driver is that it cannot receive
> asynchronous notifications and must poll the backend to check if any
> notifications were issued."
>
>    http://jdbc.postgresql.org/documentation/84/listennotify.html
>
> .... and show a `SELECT 1' being issued to push any notifications.
>
> I'd assumed that was a JDBC limitation until I tested with psql and
> found that it, too, required some kind of client-initiated communication
> to see NOTIFY events, at which point I began wondering if the backend
> pushed them at all rather than waiting for client interaction. Hence my
> question.
>
>
> Anyway, as pointed out, psql just doesn't bother polling for
> notifications because it's not important for psql, but it could if it
> needed to - the notifications are waiting in its recieve buffer for it
> to notice and care.
>
> As for the JDBC driver - it turns out that the documentation is
> out-of-date and/or misleading. The JDBC driver *does* support reading
> notifications the backend has pushed to its receive buffer, and does
> *not* have to poll the backend or issue a statement to receive
> notifications. Some searching suggests that this changed in 8.0 or 8.1 .
> The documentation needs adjusting, so I've sent a patch to it off to the
> JDBC folks.
>
> --
> Craig Ringer
>


Re: Cheapest way to poll for notifications? & Driver improvement question re SSL and notify

От
Craig Ringer
Дата:
Maciek Sakrejda wrote:

> Does the jdbc driver work with EmptyQueryResponse? At the protocol
> level, if you send a Query message with an all-whitespace sql string,
> the backend is supposed to reply with a single EmptyQueryResponse
> message and then issue ReadyForQuery again. I have a feeling that jdbc
> is probably "too smart" for this to work, but it could be worth a
> shot.

Even if the JDBC driver avoids sending such a query, it'd be a handy
behavior to use if explicit polling was implemented in the driver
interface. Send an empty Query message, read() from the buffer now that
you know there's something in it (the server's empty query response) and
see if there are any async notifications in the buffer before the empty
query response.

Thanks for the tip. If the JDBC folks ever stick their heads up here to
comment on any of this or to respond to the docs patches I've sent them
I'll see if they'd accept a patch for this and put one together if so.
It wouldn't be as efficient as purely client-side polling as it'd
require a network round trip, but it'd be a whole lot simpler and would
avoid spamming the db logs.

--
Craig Ringer

Re: Cheapest way to poll for notifications? & Driver improvement question re SSL and notify

От
Maciek Sakrejda
Дата:
> So my question is: is there any particularly low-overhead statement that
> might be suitable for generating pointless client/server chat to check for
> received async notifications? Should I just use "SELECT 1" ? Or would I be
> better off using a SHOW statement like "SHOW role" to avoid creating a
> snapshot etc?
>

Does the jdbc driver work with EmptyQueryResponse? At the protocol
level, if you send a Query message with an all-whitespace sql string,
the backend is supposed to reply with a single EmptyQueryResponse
message and then issue ReadyForQuery again. I have a feeling that jdbc
is probably "too smart" for this to work, but it could be worth a
shot.

---
Maciek Sakrejda | Software Engineer | Truviso

1065 E. Hillsdale Blvd., Suite 230
Foster City, CA 94404
(650) 242-3500 Main
(650) 242-3501 F
msakrejda@truviso.com
www.truviso.com

Re: Cheapest way to poll for notifications? & Driver improvement question re SSL and notify

От
Oliver Jowett
Дата:
Craig Ringer wrote:

> === Why can't JDBC/SSL just test for data ready to read, anyway? ===

Yeah, the SSL interface does suck :(

I am wondering if we should look at a dedicated read thread per
connection. In the past I avoided this because it doesn't scale to large
numbers of connections, and there may be some overhead from context
switching on I/O (though I haven't measured this). But between issues
with notifications+SSL, and the increasing number of reports of I/O
deadlocks, maybe we should look at it again.

-O

Re: Cheapest way to poll for notifications? & Driver improvement question re SSL and notify

От
Craig Ringer
Дата:
Oliver Jowett wrote:
> Craig Ringer wrote:
>
>> === Why can't JDBC/SSL just test for data ready to read, anyway? ===
>
> Yeah, the SSL interface does suck :(
>
> I am wondering if we should look at a dedicated read thread per
> connection. In the past I avoided this because it doesn't scale to large
> numbers of connections, and there may be some overhead from context
> switching on I/O (though I haven't measured this). But between issues
> with notifications+SSL, and the increasing number of reports of I/O
> deadlocks, maybe we should look at it again.

That'll double the number of threads required for apps that already use
one thread per JDBC connection, though. Threads in Java are cheap, but
they're not free.

Are there likely to be circumstances where it's not acceptable for the
JDBC driver to require its own internal thread(s)? Where it _has_ to be
able to do its work on one thread?

Does the Pg JDBC driver have to be able to support green threads? If so,
it can't block in one thread and expect another thread's actions to
unblock the first thread, since they're both really the same OS thread
and when one blocks, they all block.

I'm a bit concerned that adding the requirement of one thread per JDBC
connection will do nasty things to some workloads that are currently
quite happy with the way things are. Ugly as the current SSL situation
and the handling of listen/notify is, it *is* a corner case and it does
have a decent workaround.

The other deadlocks you mention are more worrying, and I've seen
discussion here that suggests that some of the issues just aren't
fixable without the ability to read from a socket without blocking.
Consuming accumulating NOTICE messages so they don't fill up the read
buffer, for example.

I suspect that it'd be wise to make the use of one thread per connection
optional because of concerns like the above. I do think it might be
very, very nice to have, though.

I'll see if I can hack together a patch for the approach I was talking
about in my previous patch and see if it works.




Thinking less conservatively: If the java.nio API (JDK>=1.4) and
SSLEngine (JDK>=1.5) were used - for the JDBC4 driver only - then it'd
be possible to provide a pool of one or more threads dedicated to
handling the network chat for the driver's connection(s), by using the
connections in non-blocking mode via SelectableChannel:

http://java.sun.com/j2se/1.5.0/docs/api/java/nio/channels/SelectableChannel.html
http://java.sun.com/j2se/1.5.0/docs/api/java/nio/channels/Selector.html

then using SSLEngine on top to maintain the SSL state of each JDBC
connection. This would basically turn the JDBC driver connection/chat
handling into a state machine.

The popular SSLSocketChannel that hides much of the SSL gruesome-ness of
nio and SSLEngine use appears to be a SelectableChannel:

http://www.rmiproxy.com/ScalableSSL/javadoc/scalablessl/SSLSocketChannel.html

... so there are possibilities for hiding SSL gore behind that.

Of course, that's not exactly a trivial conversion (understatement of
the century award) even with SSLSocketChannel to hide much of the SSL
ugly-ness. It'd certainly be a nice way to keep connections separated
from threads working with those connections, though, and let apps use
anything from one thread for all work through to one thread per JDBC
connection. The Java 5 ExecutorService even provides a nice way to
configure and control that sort of thing.

http://java.sun.com/j2se/1.5.0/docs/api/java/util/concurrent/ExecutorService.html

So ... if I was to go frothing, drooling mad and start writing a new
JDBC driver now, that's probably how I'd do it - as a PostgreSQL
protocol state machine with an associated SelectableChannel for comms,
controlled via a Selector using an ExecutorService to manage the work.

--
Craig Ringer

Re: Cheapest way to poll for notifications? & Driver improvement question re SSL and notify

От
Craig Ringer
Дата:
Maciek Sakrejda wrote:
>> So my question is: is there any particularly low-overhead statement that
>> might be suitable for generating pointless client/server chat to check for
>> received async notifications? Should I just use "SELECT 1" ? Or would I be
>> better off using a SHOW statement like "SHOW role" to avoid creating a
>> snapshot etc?
>>
>
> Does the jdbc driver work with EmptyQueryResponse?

It seems to.

> At the protocol
> level, if you send a Query message with an all-whitespace sql string,
> the backend is supposed to reply with a single EmptyQueryResponse
> message and then issue ReadyForQuery again. I have a feeling that jdbc
> is probably "too smart" for this to work, but it could be worth a
> shot.

The JDBC driver isn't too smart for this - it doesn't catch the empty
query, but instead merrily passes it on to the backend as part of an
extended query request.

See the attached text file - it shows the client/server chat for one
such round trip.

So: the server doesn't consider the empty query an error, so it won't
affect any currently running transactions. It's a cheap single-message
each way round-trip, and it doesn't have any planning or snapshot
creation costs. Looks good to me :-)

Since I can't imagine an app _needing_ the JDBC driver to ignore empty
queries, is this something that it might be reasonable to document as
expected behavior from the driver - that it _will_ send even empty
queries to the server?

Thanks _VERY_ much for the tip. You've saved me and my logs quite a bit
of pain. It's not as good as client-side-only polling, but it's a whole
nicer than a full dummy statement, and I can easily do it only when an
SSL connection is detected.



--
Craig Ringer
No.     Time        Source                Destination           Protocol Info
    178 40.633175   127.0.0.1             127.0.0.1             PGSQL    >P/B/D/E/S

Frame 178 (110 bytes on wire, 110 bytes captured)
Ethernet II, Src: 00:00:00_00:00:00 (00:00:00:00:00:00), Dst: 00:00:00_00:00:00 (00:00:00:00:00:00)
Internet Protocol, Src: 127.0.0.1 (127.0.0.1), Dst: 127.0.0.1 (127.0.0.1)
Transmission Control Protocol, Src Port: 59141 (59141), Dst Port: postgresql (5432), Seq: 3574, Ack: 53702, Len: 44
PostgreSQL
    Type: Parse
    Length: 8
    Statement:
    Query:
    Parameters: 0
PostgreSQL
    Type: Bind
    Length: 12
    Portal:
    Statement:
    Parameter formats: 0
    Parameter values: 0
    Result formats: 0
PostgreSQL
    Type: Describe
    Length: 6
    Portal:
PostgreSQL
    Type: Execute
    Length: 9
    Portal:
    Returns: all rows
PostgreSQL
    Type: Sync
    Length: 4

No.     Time        Source                Destination           Protocol Info
    179 40.633290   127.0.0.1             127.0.0.1             PGSQL    <1/2/n/I/Z

Frame 179 (92 bytes on wire, 92 bytes captured)
Ethernet II, Src: 00:00:00_00:00:00 (00:00:00:00:00:00), Dst: 00:00:00_00:00:00 (00:00:00:00:00:00)
Internet Protocol, Src: 127.0.0.1 (127.0.0.1), Dst: 127.0.0.1 (127.0.0.1)
Transmission Control Protocol, Src Port: postgresql (5432), Dst Port: 59141 (59141), Seq: 53702, Ack: 3618, Len: 26
PostgreSQL
    Type: Parse completion
    Length: 4
PostgreSQL
    Type: Bind completion
    Length: 4
PostgreSQL
    Type: No data
    Length: 4
PostgreSQL
    Type: Empty query
    Length: 4
PostgreSQL
    Type: Ready for query
    Length: 5
    Status: Idle (73)

Hello,

I don't know exactly whole topic, but I assume you want to check if there
are some available bytes on SSL socket stream to check for some incoming
messages, but you can't make this, as the available() always return 0.

There is some solution, to check if something is on wire you need ask the
underlying "plain" socket. Currently in driver there is
PGStream.changeSocket, which replaces and makes unavailable underlying
socket with it SSL wrapper, in my opinion this could be renamed and
reconstructed to something like wrapSocket, or
it could be better to allow them creating of SSL socket, by passing the
SSLFactory to it (some solution to save old socket, and make method name
accurate). This could allow PGStream to store "plain" socket, use it the
hasMessagePending (and expose the method
e.g. getPlainAvailbaleBytes() { return
plainSocket.getInputStream().available() }).

BUT...
One of disadvantage of checking plain socket is that available or read
uses "under" SSL Layer bytes, which include encrypted data, handshaking
data (the SSL supports renegotiation and session changes...?), and other
protocol specific, with no sense for application. But generally when whole
SSL socket bytes are read, then plain socket _should_ be "empty" too.

I'll try to submit proposed patch, if you think this is a some solution.

Kind regards,
Radosław Smogura

On Sat, 19 Dec 2009 15:00:35 +0800, Craig Ringer
<craig@postnewspapers.com.au> wrote:
> Hi folks
>
> Just to follow up on an earlier discussion on -general that turns out to

> be JDBC-specific: it turns out that there _is_ a need to poll for
> notifications using a dummy statement when a Java/JDBC client is using
> an SSL socket.
>
> The short version is that the JDBC driver can't check an SSL socket to
> see if any data is availible for reading - the check always returns 0
> due to a limitation in the underling SSLSocket provided by the JRE. So a

> JDBC client using SSL must still send dummy statements to get
> notifications.
>
> So my question is: is there any particularly low-overhead statement that

> might be suitable for generating pointless client/server chat to check
> for received async notifications? Should I just use "SELECT 1" ? Or
> would I be better off using a SHOW statement like "SHOW role" to avoid
> creating a snapshot etc?
>
> I had a look at the v3 protocol documentatation and didn't see any sort
> of "echo" or "ping"-type message that might be used to (a) test the
> server for aliveness and (b) guarantee readable data of a known size on
> the client's input stream. So the polling looks like it has to be done
> at the SQL level not the protocol level.
>
>
>
>
> === alternative: blocking getNotifications() ===
>
> An alternative is to provide an alternate form of getNotifications()
> that can block. It'd be unsynchronized, being intended for a dedicated
> thread in the app to use to poll for notifications. It'd call a blocking

> equivalent to QueryExecutorImpl.processNotifies() ( let's call it
> waitForNoitifies() ) that didn't check available() before attempting to
> read from the input stream.
>
> The problem here is that while PGStream.readChar() as called from
> QueryExecutorImpl.waitForNotifies() was blocked waiting for input,
> someone else in another thread might try to read from the PGStream while

> doing normal work. PGStream would have to be able to block that read
> until the readChar() from processNotifies() returned, AND would have to
> be able to push the result of readChar() back onto the
> VisibleBufferedInputStream used by PGStream if it wasn't an async
> notification message.
>
> I don't know how to do that without incurring plenty of nasty
> synchronization overhead.
>
> So, what I'm wondering is if it's worth having an alternative stream
> class, say PGSynchronizedStream, that extends a PGStream with thread
> safety. The driver user could, via the PGConnection interface, request
> that blocking notification checking be enabled, causing the usual
> PGStream to be replaced with PGSynchronizedStream. It would then be
> possible to call something like getNotificationsBlocking() to trigger
> QueryExecutorImpl.waitForNotifies() as described above.
>
> The only other change needed to support this would be add a pushChar()
> method to VisibleBufferedInputStream to permit input the blocking
> notification checker read but didn't want to be pushed back into the
> input stream.
>
> This way, if you wanted async notifications over an SSL socket you'd
> have to pay the price of some read-synchronization overhead in
> PGSynchronizedStream, but otherwise not much would change anywhere in
> the code.
>
> Is this crazy? Is there something obvious I've missed?
>
>
>
> === Why can't JDBC/SSL just test for data ready to read, anyway? ===
>
> The server can send async notifications over an SSL socket, no problem.
> It generates an appropriate SSL message via the ssl library and sends it

> down the wire.
>
> A Java SSL client, though, cannot check to see if it can read from an
> SSL socket without blocking. InputStream.available() always returns zero

> on a Java SSL socket, because while there may be data in the underlying
> connection buffer, the SSL client isn't sure if (a) it's a full SSL
> message, and (b) if that message contains data for the client. It
> doesn't seem to want to do the processing and buffering required to
> figure that out in the available() call.
>
> It's an annoying issue. In theory there's nothing that prevents
> non-blocking I/O on SSL sockets - OpenSSL can do it, with a few quirks.
> Java's SSLSocket can't do it, though. To get non-blocking SSL in Java
> you apparently have to completely re-write your client using java.nio
> async I/O and use the SSLEngine to do manual SSL handling on top of
> that. There's no standard friendly-to-use non-blocking SSL socket
> wrapper on top of that, and direct use of SSLEngine is ...
"interesting".
>
> There are 3rd party implementations of wrappers that make a java.nio &
> SSLEngine-based system look like a normal SSLSocket, like ScalableSSL's
> SSLSocketChannel. that brings behaviour much like OpenSSL's
> almost-transparent non-blocking SSL - ie it looks like a normal
> non-blocking socket except for a few quirks re handshaking.
> SSLSocketChannel still doesn't do available() checking, though the docs
> say it can be added.
>
> Even if that was sorted out though, SSLEngine is also present only in
> JDK 1.5 and above, so the JDBC driver can't use it for a while yet.
>
>
>
> On 11/12/2009 11:39 PM, Craig Ringer wrote:
>> Scott, Tom, Merlin:
>>
>> Thanks for the comments and help. It's all sorted now - the origin of
>> the confusion was some outdated information in the JDBC driver
>> documentation.
>>
>> The question arose because I was originally looking at polling from
JDBC
>> (which I know I forgot to mention), where the docs state that:
>>
>> "A key limitation of the JDBC driver is that it cannot receive
>> asynchronous notifications and must poll the backend to check if any
>> notifications were issued."
>>
>>    http://jdbc.postgresql.org/documentation/84/listennotify.html
>>
>> .... and show a `SELECT 1' being issued to push any notifications.
>>
>> I'd assumed that was a JDBC limitation until I tested with psql and
>> found that it, too, required some kind of client-initiated
communication
>> to see NOTIFY events, at which point I began wondering if the backend
>> pushed them at all rather than waiting for client interaction. Hence my
>> question.
>>
>>
>> Anyway, as pointed out, psql just doesn't bother polling for
>> notifications because it's not important for psql, but it could if it
>> needed to - the notifications are waiting in its recieve buffer for it
>> to notice and care.
>>
>> As for the JDBC driver - it turns out that the documentation is
>> out-of-date and/or misleading. The JDBC driver *does* support reading
>> notifications the backend has pushed to its receive buffer, and does
>> *not* have to poll the backend or issue a statement to receive
>> notifications. Some searching suggests that this changed in 8.0 or 8.1
.
>> The documentation needs adjusting, so I've sent a patch to it off to
the
>> JDBC folks.
>>
>> --
>> Craig Ringer
>>

Re: Cheapest way to poll for notifications? & Driver improvement question re SSL and notify

От
Craig Ringer
Дата:
On 21/12/2009 5:41 PM, rsmogura@softperience.pl wrote:

> One of disadvantage of checking plain socket is that available or read
> uses "under" SSL Layer bytes, which include encrypted data, handshaking
> data (the SSL supports renegotiation and session changes...?), and other
> protocol specific, with no sense for application. But generally when whole
> SSL socket bytes are read, then plain socket _should_ be "empty" too.

Yes - when the plain socket is empty, the SSL socket is also empty. That
does not imply the inverse, though.

If the plain socket is NOT empty, that does not mean that the SSL socket
is also NOT empty. As you said, the plain socket underlying the SSL
socket may have bytes available() but they're just an SSL re-negotiation
request or the like. So if you try to read from the SSL socket in this
case, you will still block, even though the underlying socket did have
bytes available to read.

For available() on an ssl socket to work, you would need to implement it
by using the underlying SSL implementation to read any data buffered on
the plain socket (if any), process it, and return the amount of client
data in it if any. So if the underlying socket's available() returns 0,
your SSL available() returns 0 also. Otherwise it reads what's there,
decodes it if it can, and returns how much readable user data it got.

Unfortunately this can't be done with Java's SSLSocket, since you have
no access to the underlying SSL engine implementation. It *can* be done
with the Java 5 java.nio API and SSLEngine, possibly via a wrapper like
SSLSocketChannel, though. In fact, if you're building on java.nio and
SSLSocketChannel you can use exactly the approach described above.

Really, the requirements to make this work are:

   - a non-blocking SSL socket; or
   - a thread that can afford to block on the socket

--
Craig Ringer

Re: Cheapest way to poll for notifications? & Driver improvement question re SSL and notify

От
Craig Ringer
Дата:
(Re-sent, this time to the list)

On 21/12/2009 9:13 PM, rsmogura@softperience.pl wrote:

> I haven't seen 1.4.2 JDK for ages :), but there is method
> javax.net.ssl.SSLSocketFactory.createSocket that takes as the 1st argument
> plain socket, there is no need to "forgot" plain socket (and it can be
> used, actually it's used for SSL communication with lazy handshake
> FTPS/SMTPS...).

That's how the PgJDBC driver works - it wraps an existing socket in an
SSLSocket when SSL negotiation begins. Pg always begins with a plain
text connection - it doesn't have a separate SSL port - so it has to
begin with a plaintext connection and then request SSL negotiation using
a plaintext message.

> Unfortunatly plainSocket can have some available bytes, but sslsoket.read
> can return EOF. But this was i saw on SUN JDK is that read(new byte[0]) on
> SSL socket causes process plain data.

I'm pretty sure it also blocks if there's nothing to read. You'd have to
run that in a background thread to force processing of any pending data
by the SSL engine. If you're going to do that, you may as well just have
a dedicated background thread to do all the reading from the socket...

--
Craig Ringer

On Mon, 21 Dec 2009 21:44:00 +0800, Craig Ringer
<craig@postnewspapers.com.au> wrote:
> (Re-sent, this time to the list)
>
> On 21/12/2009 9:13 PM, rsmogura@softperience.pl wrote:
>
>> I haven't seen 1.4.2 JDK for ages :), but there is method
>> javax.net.ssl.SSLSocketFactory.createSocket that takes as the 1st
>> argument
>> plain socket, there is no need to "forgot" plain socket (and it can be
>> used, actually it's used for SSL communication with lazy handshake
>> FTPS/SMTPS...).
>
> That's how the PgJDBC driver works - it wraps an existing socket in an
> SSLSocket when SSL negotiation begins. Pg always begins with a plain
> text connection - it doesn't have a separate SSL port - so it has to
> begin with a plaintext connection and then request SSL negotiation using

> a plaintext message.
But I think we can leave plain socket somewhere to call available().

>> Unfortunatly plainSocket can have some available bytes, but
sslsoket.read
>> can return EOF. But this was i saw on SUN JDK is that read(new byte[0])
>> on
>> SSL socket causes process plain data.
>
> I'm pretty sure it also blocks if there's nothing to read. You'd have to

> run that in a background thread to force processing of any pending data
> by the SSL engine. If you're going to do that, you may as well just have

> a dedicated background thread to do all the reading from the socket...
It's not block, I tested on HTTPS.


I think the background thread, especially timer thread is better solution
then sending data to server.

Re: Cheapest way to poll for notifications? & Driver improvement question re SSL and notify

От
Віталій Тимчишин
Дата:


2009/12/21 <rsmogura@softperience.pl>

I think the background thread, especially timer thread is better solution
then sending data to server.


I disagree because this task (receive notifications) is not an often task. There are many many installations that do not need it. And  prefer to implement such a task in inefficient way than to make all the connections in the world more complex and resource-consuming.

Best regards, Vitalii Tymchyshyn