1 module hunt.http.codec.http.stream.SimpleFlowControlStrategy; 2 3 import hunt.http.codec.http.stream.AbstractFlowControlStrategy; 4 import hunt.http.codec.http.stream.SessionSPI; 5 import hunt.http.codec.http.stream.StreamSPI; 6 7 import hunt.http.codec.http.frame.Frame; 8 import hunt.http.codec.http.frame.WindowUpdateFrame; 9 import hunt.util.Common; 10 11 import hunt.logging; 12 13 14 /** 15 */ 16 class SimpleFlowControlStrategy :AbstractFlowControlStrategy { 17 this() { 18 this(DEFAULT_WINDOW_SIZE); 19 } 20 21 this(int initialStreamSendWindow) { 22 super(initialStreamSendWindow); 23 } 24 25 override 26 void onDataConsumed(SessionSPI session, StreamSPI stream, int length) { 27 if (length <= 0) 28 return; 29 30 // This is the simple algorithm for flow control. 31 // This method is called when a whole flow controlled frame has been 32 // consumed. 33 // We send a WindowUpdate every time, even if the frame was very small. 34 35 WindowUpdateFrame sessionFrame = new WindowUpdateFrame(0, length); 36 session.updateRecvWindow(length); 37 version(HUNT_DEBUG) 38 tracef("Data consumed, increased session recv window by %s for %s", length, session); 39 40 Frame[] streamFrame = Frame.EMPTY_ARRAY; 41 if (stream !is null) { 42 if (stream.isRemotelyClosed()) { 43 version(HUNT_DEBUG) { 44 tracef("Data consumed, ignoring update stream recv window by %s for remotely closed %s", length, stream); 45 } 46 } else { 47 streamFrame = new Frame[1]; 48 streamFrame[0] = new WindowUpdateFrame(stream.getId(), length); 49 stream.updateRecvWindow(length); 50 version(HUNT_DEBUG) 51 tracef("Data consumed, increased stream recv window by %s for %s", length, stream); 52 } 53 } 54 55 session.frames(stream, Callback.NOOP, sessionFrame, streamFrame); 56 } 57 }