3535import spotty .common .utils .ExceptionalRunnable ;
3636import spotty .server .connection .socket .SpottySocket ;
3737import spotty .server .connection .state .ConnectionState ;
38+ import spotty .server .event .ServerEvents ;
3839import spotty .server .handler .exception .ExceptionHandler ;
3940import spotty .server .handler .request .RequestHandler ;
4041import spotty .server .registry .exception .ExceptionHandlerRegistry ;
@@ -108,36 +109,26 @@ public final class Connection extends StateMachine<ConnectionState> implements C
108109 private SpottySocket socket ;
109110 private final ReactorWorker reactorWorker ;
110111 private final ExceptionHandlerRegistry exceptionHandlerRegistry ;
112+ private final ServerEvents serverEvents ;
111113 private final int maxRequestBodySize ;
112114 private ByteBuffer readBuffer ;
113115 private RequestHandler requestHandler ;
116+ private SelectionKey selectionKey ;
114117
115118 private ByteBuffer headersByteBuffer ;
116119 private ByteBuffer bodyByteBuffer ;
117120
118- public Connection (SpottySocket socket ,
119- RequestHandler requestHandler ,
120- ReactorWorker reactorWorker ,
121- ExceptionHandlerRegistry exceptionHandlerRegistry ,
122- int maxRequestBodySize ) throws SpottyStreamException {
123- this (socket , requestHandler , reactorWorker , exceptionHandlerRegistry , maxRequestBodySize , DEFAULT_BUFFER_SIZE );
124- }
125-
126- public Connection (SpottySocket socket ,
127- RequestHandler requestHandler ,
128- ReactorWorker reactorWorker ,
129- ExceptionHandlerRegistry exceptionHandlerRegistry ,
130- int maxRequestBodySize ,
131- int bufferSize ) throws SpottyStreamException {
121+ private Connection (Builder builder ) throws SpottyStreamException {
132122 super (INITIALIZED );
133123
134- this .socket = notNull ("socket" , socket );
135- this .requestHandler = notNull ("requestHandler" , requestHandler );
136- this .reactorWorker = notNull ("reactorWorker" , reactorWorker );
137- this .exceptionHandlerRegistry = notNull ("exceptionHandlerService" , exceptionHandlerRegistry );
138- this .maxRequestBodySize = maxRequestBodySize ;
124+ this .socket = notNull ("socket" , builder .socket );
125+ this .requestHandler = notNull ("requestHandler" , builder .requestHandler );
126+ this .reactorWorker = notNull ("reactorWorker" , builder .reactorWorker );
127+ this .exceptionHandlerRegistry = notNull ("exceptionHandlerService" , builder .exceptionHandlerRegistry );
128+ this .serverEvents = notNull ("serverEvents" , builder .serverEvents );
129+ this .maxRequestBodySize = builder .maxRequestBodySize ;
139130
140- this .readBuffer = ByteBuffer .allocate (bufferSize );
131+ this .readBuffer = ByteBuffer .allocate (builder . bufferSize );
141132
142133 this .stateHandlerGraph
143134 .filter (
@@ -204,7 +195,11 @@ public void after() {
204195 }
205196
206197 public SelectionKey register (Selector selector ) {
207- return exceptionHandler (() -> socket .register (selector , OP_CONNECT , this ));
198+ if (selectionKey != null ) {
199+ throw new SpottyException ("connection has been registered already" );
200+ }
201+
202+ return selectionKey = exceptionHandler (() -> socket .register (selector , OP_CONNECT , this ));
208203 }
209204
210205 public void markDataRemaining () {
@@ -218,12 +213,15 @@ public void markReadyToRead() {
218213 }
219214
220215 public void handle () {
221- do {
222- exceptionHandler (
223- handleState ,
224- afterExceptionHandler // if exception respond error to the client
225- );
226- } while (socket .readBufferHasRemaining () && state ().isReading ());
216+ exceptionHandler (
217+ handleState ,
218+ afterExceptionHandler // if exception respond error to the client
219+ );
220+
221+ // if after connection handing socket buffer still has data then run handing in next tick
222+ if (socket .readBufferHasRemaining () && state ().isReading ()) {
223+ runHandleNextTick ();
224+ }
227225 }
228226
229227 // optimization to not spawn callback objects each time
@@ -583,14 +581,18 @@ private boolean responseWriteCompleted() {
583581
584582 changeState (READY_TO_READ );
585583
586- // has something did not process
584+ // has something did not process, add it to handle in next tick
587585 if (readBuffer .position () > 0 || socket .readBufferHasRemaining ()) {
588- handle ();
586+ runHandleNextTick ();
589587 }
590588
591589 return false ;
592590 }
593591
592+ private void runHandleNextTick () {
593+ serverEvents .add (selectionKey );
594+ }
595+
594596 private void resetResponse () {
595597 this .response .reset ();
596598 this .responseHeadersBuffer .reset ();
@@ -680,4 +682,57 @@ private <T> T exceptionHandler(ExceptionalCallable<T> runnable, Runnable afterEx
680682 return null ;
681683 }
682684
685+ public static class Builder {
686+ private SpottySocket socket ;
687+ private RequestHandler requestHandler ;
688+ private ReactorWorker reactorWorker ;
689+ private ExceptionHandlerRegistry exceptionHandlerRegistry ;
690+ private ServerEvents serverEvents ;
691+ private int maxRequestBodySize ;
692+ private int bufferSize = DEFAULT_BUFFER_SIZE ;
693+
694+ public static Builder connection () {
695+ return new Builder ();
696+ }
697+
698+ public Builder socket (SpottySocket socket ) {
699+ this .socket = socket ;
700+ return this ;
701+ }
702+
703+ public Builder requestHandler (RequestHandler requestHandler ) {
704+ this .requestHandler = requestHandler ;
705+ return this ;
706+ }
707+
708+ public Builder reactorWorker (ReactorWorker reactorWorker ) {
709+ this .reactorWorker = reactorWorker ;
710+ return this ;
711+ }
712+
713+ public Builder exceptionHandlerRegistry (ExceptionHandlerRegistry exceptionHandlerRegistry ) {
714+ this .exceptionHandlerRegistry = exceptionHandlerRegistry ;
715+ return this ;
716+ }
717+
718+ public Builder serverEvents (ServerEvents serverEvents ) {
719+ this .serverEvents = serverEvents ;
720+ return this ;
721+ }
722+
723+ public Builder maxRequestBodySize (int maxRequestBodySize ) {
724+ this .maxRequestBodySize = maxRequestBodySize ;
725+ return this ;
726+ }
727+
728+ public Builder bufferSize (int bufferSize ) {
729+ this .bufferSize = bufferSize ;
730+ return this ;
731+ }
732+
733+ public Connection build () {
734+ return new Connection (this );
735+ }
736+ }
737+
683738}
0 commit comments