1251877SpeterAPACHE COMMONS: serf                                    -*-indented-text-*-
2251877Speter
3251877Speter
4251877SpeterTOPICS
5251877Speter
6251877Speter  1. Introduction
7251877Speter  2. Thread Safety
8251877Speter  3. Pool Usage
9251877Speter  4. Bucket Read Functions
10251877Speter  5. Versioning
11251877Speter  6. Bucket lifetimes
12251877Speter
13251877Speter
14251877Speter-----------------------------------------------------------------------------
15251877Speter
16251877Speter1. INTRODUCTION
17251877Speter
18251877SpeterThis document details various design choices for the serf library. It
19251877Speteris intended to be a guide for serf developers. Of course, these design
20251877Speterprinciples, choices made, etc are a good source of information for
21251877Speterusers of the serf library, too.
22251877Speter
23251877Speter
24251877Speter-----------------------------------------------------------------------------
25251877Speter
26251877Speter2. THREAD SAFETY
27251877Speter
28251877SpeterThe serf library should contain no mutable globals, making it is safe
29251877Speterto use in a multi-threaded environment.
30251877Speter
31251877SpeterEach "object" within the system does not need to be used from multiple
32251877Speterthreads at a time. Thus, they require no internal mutexes, and can
33251877Speterdisable mutexes within APR objects where applicable (e.g. pools that
34251877Speterare created).
35251877Speter
36251877SpeterThe objects should not have any thread affinity (i.e. don't use
37251877Speterthread-local storage). This enables an application to use external
38251877Spetermutexes to guard entry to the serf objects, which then allows the
39251877Speterobjects to be used from multiple threads.
40251877Speter
41251877Speter
42251877Speter-----------------------------------------------------------------------------
43251877Speter
44251877Speter3. POOL USAGE
45251877Speter
46251877SpeterFor general information on the proper use of pools, please see:
47251877Speter
48251877Speter  http://cvs.apache.org/viewcvs/*checkout*/apr/docs/pool-design.html
49251877Speter
50251877SpeterWithin serf itself, the buckets introduce a significant issue related
51251877Speterto pools. Since it is very possible to end up creating *many* buckets
52251877Speterwithin a transaction, and that creation could be proportional to an
53251877Speterincoming or outgoing data stream, a lot of care must be take to avoid
54251877Spetertying bucket allocations to pools. If a bucket allocated any internal
55251877Spetermemory against a pool, and if that bucket is created an unbounded
56251877Speternumber of times, then the pool memory could be exhausted.
57251877Speter
58251877SpeterThus, buckets are allocated using a custom allocator which allows the
59251877Spetermemory to be freed when that bucket is no longer needed. This
60251877Spetercontrasts with pools where the "free" operation occurs over a large
61251877Speterset of objects, which is problematic if some are still in use.
62251877Speter
63251877Speter### need more explanation of strategy/solution ...
64251877Speter
65251877Speter
66251877Speter-----------------------------------------------------------------------------
67251877Speter
68251877Speter4. BUCKET READ FUNCTIONS
69251877Speter
70251877SpeterThe bucket reading and peek functions must not block. Each read
71251877Speterfunction should return (up to) the specified amount of data. If
72251877SpeterSERF_READ_ALL_AVAIL is passed, then the function should provide
73251877Speterwhatever is immediately available, without blocking.
74251877Speter
75251877SpeterThe peek function does not take a requested length because it is
76251877Speternon-destructive. It is not possible to "read past" any barrier with a
77251877Speterpeek function. Thus, peek should operate like SERF_READ_ALL_AVAIL.
78251877Speter
79251877SpeterThe return values from the read functions should follow this general
80251877Speterpattern:
81251877Speter
82251877Speter    APR_SUCCESS    Some data was returned, and the caller can
83251877Speter                   immediately call the read function again to read
84251877Speter                   more data.
85251877Speter
86251877Speter                   NOTE: when bucket behavior tracking is enabled,
87251877Speter                   then you must read more data from this bucket
88251877Speter                   before returning to the serf context loop. If a
89251877Speter                   bucket is not completely drained first, then it is
90251877Speter                   possible to deadlock (the server might not read
91251877Speter                   anything until you read everything it has already
92251877Speter                   given to you).
93251877Speter
94251877Speter    APR_EAGAIN     Some data was returned, but no more is available
95251877Speter                   for now. The caller must "wait for a bit" or wait
96251877Speter                   for some event before attempting to read again
97251877Speter                   (basically, this simply means re-run the serf
98251877Speter                   context loop). Though it shouldn't be done, reading
99251877Speter                   again will, in all likelihood, return zero length
100251877Speter                   data and APR_EAGAIN again.
101251877Speter
102251877Speter                   NOTE: when bucket behavior tracking is enabled,
103251877Speter                   then it is illegal to immediately read a bucket
104251877Speter                   again after it has returned APR_EAGAIN. You must
105251877Speter                   run the serf context loop again to (potentially)
106251877Speter                   fetch more data for the bucket.
107251877Speter
108251877Speter    APR_EOF        Some data was returned, and this bucket has no more
109251877Speter                   data available and should not be read again. If you
110251877Speter                   happen to read it again, then it will return zero
111251877Speter                   length data and APR_EOF.
112251877Speter
113251877Speter                   NOTE: when bucket behavior tracking is enabled,
114251877Speter                   then it is illegal to read this bucket ever again.
115251877Speter
116251877Speter    other          An error has occurred. No data was returned. The
117251877Speter                   returned length is undefined.
118251877Speter
119251877SpeterIn the above paragraphs, when it says "some data was returned", note
120251877Speterthat this could be data of length zero.
121251877Speter
122251877SpeterIf a length of zero is returned, then the caller should not attempt to
123251877Speterdereference the data pointer. It may be invalid. Note that there is no
124251877Speterreason to dereference that pointer, since it doesn't point to any
125251877Spetervalid data.
126251877Speter
127251877SpeterAny data returned by the bucket should live as long as the bucket, or
128251877Speteruntil the next read or peek occurs.
129251877Speter
130251877SpeterThe read_bucket function falls into a very different pattern. See its
131251877Speterdoc string for more information.
132251877Speter
133251877Speter
134251877Speter-----------------------------------------------------------------------------
135251877Speter
136251877Speter5. VERSIONING
137251877Speter
138251877SpeterThe serf project uses the APR versioning guidelines described here:
139251877Speter
140251877Speter  http://apr.apache.org/versioning.html
141251877Speter
142251877Speter
143251877Speter-----------------------------------------------------------------------------
144251877Speter
145251877Speter6. BUCKET LIFETIMES
146251877Speter
147251877Speter### flesh out. basically: if you hold a bucket pointer, then you own
148251877Speter### it. passing a bucket into another transfers ownership. use barrier
149251877Speter### buckets to limit destruction of a tree of buckets.
150251877Speter
151251877Speter
152251877Speter-----------------------------------------------------------------------------
153