Revision created by MOE tool push_codebase.
[gae.git] / java / src / main / com / google / appengine / api / files / FileWriteChannel.java
blob65e503b794133c9fc20bb67eefd432a827197fe7
1 // Copyright 2011 Google Inc. All Rights Reserved.
3 package com.google.appengine.api.files;
5 import java.io.IOException;
6 import java.nio.ByteBuffer;
7 import java.nio.channels.WritableByteChannel;
9 /**
10 * A {@code WritableByteChannel} for appending bytes to an
11 * {@link AppEngineFile}. In addition to the behavior specified by {@code
12 * WritableByteChannel} this class also exposes a
13 * {@link #write(ByteBuffer, String) sequence key} feature which may be used to
14 * recover from certain types of failures.
15 * <p>
16 * An instance of {@code FileWriteChannel} is obtained from the method
17 * {@link FileService#openWriteChannel(AppEngineFile, boolean)}.
18 * <p>
19 * A {@code FileWriteChannel} is associated with a single App Engine request and
20 * may not be used outside of the request in which it is constructed. Therefore
21 * an instance of {@code FileWriteChannel} should not be cached between
22 * requests. Instead, {@link #close() close } the channel at the end of the
23 * request (without {@link #closeFinally() finalizing}), cache the {@code
24 * AppEngineFile} or just the {@link AppEngineFile#getFullPath() path}, and
25 * create a new {@code FileWriteChannel} in a later request.
26 * <p>
27 * When the channel is
28 * {@link FileService#openWriteChannel(AppEngineFile, boolean) opened}, the
29 * underlying file may be <b>locked</b>. Successful aquisition of the
30 * lock means that no other App Engine request will be able to read or write the
31 * underlying file until the lock is released.
32 * <p>
33 * One of the {@code close()} methods should be invoked before the request
34 * terminates. The version {@link #closeFinally()} causes the underlying file to
35 * be <i>finalized</i>. Once a file is finalized it may be read, and it may not
36 * be written. In order to finalize a file it is necessary to hold the lock for
37 * the file. If no {@code close()} method is invoked before the request
38 * terminates then {@link #close()} will implicitly be invoked and so the file
39 * will not be finalized. All of the {@code close()} methods have the
40 * side-effect of releasing a lock if one is held.
42 * Just like {@link WritableByteChannel} If one thread initiates a write operation upon a channel
43 * then any other thread that attempts to initiate another write operation will block until the
44 * first operation is complete.
47 public interface FileWriteChannel extends WritableByteChannel {
49 /**
50 * As specified by {@link WritableByteChannel#write(ByteBuffer)} with the
51 * addition of the {@code sequenceKey} parameter. If this parameter is not
52 * {@code null} then it will be passed to the back end repository and recorded
53 * as the last good sequence key if the back end write succeeds. In this case,
54 * if the {@code sequenceKey} is not strictly lexicographically greater than
55 * the last good sequence key the back end has already recorded (if there is
56 * one), a {@link KeyOrderingException} will be thrown from which the last
57 * good sequence key may be retrieved via the method
58 * {@link KeyOrderingException#getLastGoodSequenceKey()}. By making use of
59 * this feedback system it is possible to recover from certain types of
60 * failures that it would otherwise be difficult to recover from. For example,
61 * if bytes are being written to a file in a series of App Engine Task Queue
62 * tasks and one of the tasks is retried, this technique can be used to avoid
63 * writing the same bytes twice. As another example, if during a series of
64 * writes the back end loses some of the bytes of a file due to a back end
65 * system failure, this feedback system may be used to inform the client of
66 * the last write after which the data corruption begins, thus enabling the
67 * client to resend all bytes after that point.
69 public int write(ByteBuffer src, String sequenceKey) throws IOException;
71 /**
72 * Close the channel and finalize the file. After the file is finalized it may
73 * be read, and it may no longer be written.
75 * @throws IllegalStateException if the current request does not hold the lock
76 * for the file
77 * @throws IOException if any unexpected problem occurs
79 public void closeFinally() throws IllegalStateException, IOException;