Class UploadReservation
- All Implemented Interfaces:
IUploadReservation
Concurrency. Strictly one chunk in flight per reservation: the servlet takes tryLock() around its state check, offset compare, append, sidecar rewrite and timer re-arm; a second concurrent request for the same reservation fails the try-lock and is answered 409 busy without reading its body. The registry takes the same lock for cancellation, pause, resume and state changes.
Nobody waits for a chunk. A chunk can take as long as the client's network makes it, so a pause, resume, cancellation or consumption that finds the lock taken is not made to wait: the registry hands it to defer(Runnable), and it is run, in the order of the calls, by whoever holds the lock - at the latest when that thread releases it (unlock()), and earlier by the servlet, which gives up the chunk it is receiving when a call that stops the file is waiting (UploadFileEntry.isInterruptPending()).
Pause. A file is UploadState.PAUSED while the App or the client holds it; the reservation is paused as a whole (isPaused()) when no file is receiving and at least one is paused, and then its idle and start timers are suspended and the maximum pause timer runs. The registry keeps the flags and timers; this class only reads them.
- Author:
- Christopher Mindus
Method Summary
Modifier and TypeMethodDescriptionvoidCancels one file or the whole reservation.intGets the chunk size the client must use, in bytes.getFile(int fid) Gets a file entry by index.getFiles()Gets the files, accepted or refused, in the order they were requested; a file's index in this list is itsIUploadFile.getFileIndex().getID()--- IUploadReservation ---intGets the idle timeout in force, in seconds.Gets the limits in force when the reservation was made.Gets the per-reservation listener.intGets the maximum file count per reservation in force.intGets the maximum pause time in force, in seconds: how long the reservation may stay paused (by the App or the client) before it is cancelled with reasonmaxPause.getPath()Gets the relative upload path, ending with '/'.Gets the permitted media types in force, as configured, empty for any.Gets the reason the whole reservation was refused.longGets the remaining allowance after this reservation, i.e.getSecret(int fileIndex) Gets the per-file secret.Gets the application session UUID this reservation belongs to.longSums the declared sizes of the files that still hold quota: every file whose state is not terminal.booleanChecks if the reservation as a whole was accepted.booleanChecks if the reservation was cancelled as a whole.booleanisClosed()Checks if every file has reached a terminal state or been verified, i.e.booleanChecks if the current thread holds the lock.booleanChecks if the App wants the automatic failure notice for this reservation: a cancellation only the server knows about (idle,start,maxPause) is then shown to the client as one message box listing the files.booleanisPaused()Checks if the reservation is paused as a whole: no file is receiving chunks and at least one isUploadState.PAUSED.static booleanisReceiving(IUploadFile file) Checks if a file is accepted and not final: the servlet may append to it.booleanChecks if every file is terminal, i.e.voidlock()Takes the reservation lock, waiting if necessary (registry and service use; the servlet usestryLock()so a second chunk in flight is refused rather than queued).voidPauses one file or every receiving file: the client is told to stop sending and a chunk sent anyway is refused as paused, never as a failure.voidresume(int fileIndex) Resumes one file or every file the App paused: the client is told it may send again.voidRuns the changes that found the lock taken, in the order of the calls; the caller holds the lock.toString()Outputs to string.booleantryLock()Tries to take the reservation lock without waiting.voidunlock()Releases the reservation lock, and when that frees it, runs the changes that found it taken meanwhile (defer(Runnable)).
Method Details
tryLock
public boolean tryLock()Tries to take the reservation lock without waiting.- Returns:
- true if taken; the caller must
unlock().
lock
public void lock()Takes the reservation lock, waiting if necessary (registry and service use; the servlet usestryLock()so a second chunk in flight is refused rather than queued).getSessionUUID
Gets the application session UUID this reservation belongs to.- Returns:
- The UUID string.
getLimits
Gets the limits in force when the reservation was made.- Returns:
- The limits.
getListener
Gets the per-reservation listener.- Returns:
- The listener, or null.
unlock
public void unlock()Releases the reservation lock, and when that frees it, runs the changes that found it taken meanwhile (defer(Runnable)).runPending
public void runPending()Runs the changes that found the lock taken, in the order of the calls; the caller holds the lock.- Throws:
IllegalStateException- If the lock is not held by the current thread.
isLockedByCurrentThread
public boolean isLockedByCurrentThread()Checks if the current thread holds the lock.- Returns:
- true if held.
getID
--- IUploadReservation ---- Specified by:
getIDin interfaceIUploadReservation- Returns:
- The ID.
getPath
Description copied from interface:IUploadReservationGets the relative upload path, ending with '/'. The client resolves it against the origin it already uses for its WebSocket; the server never composes a scheme, host or port.- Specified by:
getPathin interfaceIUploadReservation- Returns:
- The path, e.g.
/iizi-upload/.
isAccepted
public boolean isAccepted()Description copied from interface:IUploadReservationChecks if the reservation as a whole was accepted. A refused reservation has no accepted files andIUploadReservation.getRefusalReason()says why.- Specified by:
isAcceptedin interfaceIUploadReservation- Returns:
- true if accepted.
getRefusalReason
Description copied from interface:IUploadReservationGets the reason the whole reservation was refused.- Specified by:
getRefusalReasonin interfaceIUploadReservation- Returns:
- The reason, or null if accepted.
getFiles
Description copied from interface:IUploadReservationGets the files, accepted or refused, in the order they were requested; a file's index in this list is itsIUploadFile.getFileIndex().- Specified by:
getFilesin interfaceIUploadReservation- Returns:
- The files, never null.
getFile
Gets a file entry by index.- Parameters:
fid- The file index.- Returns:
- The entry, or null if out of range.
getSecret
Description copied from interface:IUploadReservationGets the per-file secret. Never log it.- Specified by:
getSecretin interfaceIUploadReservation- Parameters:
fileIndex- The file index.- Returns:
- The secret as base64url without padding, or null if the file was refused.
getChunkSize
public int getChunkSize()Description copied from interface:IUploadReservationGets the chunk size the client must use, in bytes.- Specified by:
getChunkSizein interfaceIUploadReservation- Returns:
- The chunk size.
getRemainingBytes
public long getRemainingBytes()Description copied from interface:IUploadReservationGets the remaining allowance after this reservation, i.e. the most a further reservation of the same session could declare, in bytes.- Specified by:
getRemainingBytesin interfaceIUploadReservation- Returns:
- The remaining bytes, or
Long.MAX_VALUEif unlimited.
getMaxFiles
public int getMaxFiles()Description copied from interface:IUploadReservationGets the maximum file count per reservation in force.- Specified by:
getMaxFilesin interfaceIUploadReservation- Returns:
- The count.
getPermittedTypes
Description copied from interface:IUploadReservationGets the permitted media types in force, as configured, empty for any.- Specified by:
getPermittedTypesin interfaceIUploadReservation- Returns:
- The comma-separated list.
getIdleTimeout
public int getIdleTimeout()Description copied from interface:IUploadReservationGets the idle timeout in force, in seconds.- Specified by:
getIdleTimeoutin interfaceIUploadReservation- Returns:
- The seconds after which an idle reservation is cancelled.
getMaxPause
public int getMaxPause()Description copied from interface:IUploadReservationGets the maximum pause time in force, in seconds: how long the reservation may stay paused (by the App or the client) before it is cancelled with reasonmaxPause. The idle timeout does not run while paused.- Specified by:
getMaxPausein interfaceIUploadReservation- Returns:
- The seconds.
isNoticeEnabled
public boolean isNoticeEnabled()Description copied from interface:IUploadReservationChecks if the App wants the automatic failure notice for this reservation: a cancellation only the server knows about (idle,start,maxPause) is then shown to the client as one message box listing the files. On by default.- Specified by:
isNoticeEnabledin interfaceIUploadReservation- Returns:
- true if the notice is shown, false if the App reports failures its own way.
isPaused
public boolean isPaused()Description copied from interface:IUploadReservationChecks if the reservation is paused as a whole: no file is receiving chunks and at least one isUploadState.PAUSED. The idle timeout is suspended and the maximum pause time runs.- Specified by:
isPausedin interfaceIUploadReservation- Returns:
- true if paused as a whole.
isClosed
public boolean isClosed()Description copied from interface:IUploadReservationChecks if every file has reached a terminal state or been verified, i.e. no further byte is expected.- Specified by:
isClosedin interfaceIUploadReservation- Returns:
- true if closed.
isCancelled
public boolean isCancelled()Description copied from interface:IUploadReservationChecks if the reservation was cancelled as a whole.- Specified by:
isCancelledin interfaceIUploadReservation- Returns:
- true if cancelled.
isTerminal
public boolean isTerminal()Checks if every file is terminal, i.e. the reservation holds no quota and can leave the registry.- Returns:
- true if fully terminal.
heldBytes
public long heldBytes()Sums the declared sizes of the files that still hold quota: every file whose state is not terminal.- Returns:
- The bytes held against the quotas.
cancel
Description copied from interface:IUploadReservationCancels one file or the whole reservation. Cancel means cancel: the staged bytes are deleted immediately and the quota is released.- Specified by:
cancelin interfaceIUploadReservation- Parameters:
fileIndex- The file index, or -1 for the whole reservation.reason- The reason, recorded on the file(s) and reported to the listener.
pause
Description copied from interface:IUploadReservationPauses one file or every receiving file: the client is told to stop sending and a chunk sent anyway is refused as paused, never as a failure. The listener seesIFileUploadListener.onFilePaused(IUploadReservation, IUploadFile, String). A file that is complete, verified or terminal is left alone; a file the client has already paused is additionally held by the App.- Specified by:
pausein interfaceIUploadReservation- Parameters:
fileIndex- The file index, or -1 for every file.reason- The reason, reported to the listener and the client; null or empty meanspaused.
resume
public void resume(int fileIndex) Description copied from interface:IUploadReservationResumes one file or every file the App paused: the client is told it may send again. A file the client has also paused stays paused until the client resumes it.- Specified by:
resumein interfaceIUploadReservation- Parameters:
fileIndex- The file index, or -1 for every file.
isReceiving
Checks if a file is accepted and not final: the servlet may append to it.- Parameters:
file- The file.- Returns:
- true if the file can receive chunks.
toString