You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: kitchen-sink/resource-to-sequence/resource-to-sequence.asciidoc
+44-51Lines changed: 44 additions & 51 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -4,8 +4,9 @@ by Gerrit Jansen van Vuuren
4
4
5
5
==== Problem
6
6
7
-
You have a resource that you want to access as a sequence, but you do not want to keep a connection open and close it only when the whole sequence have been read
8
-
thus potentially leaking the connection.
7
+
You have a resource that you want to access as a sequence, but you do
8
+
not want to keep a connection open and close it only when the whole
9
+
sequence have been read thus potentially leaking the connection.
9
10
10
11
==== Solution
11
12
@@ -14,59 +15,45 @@ The solution is simple.
14
15
1. A select function
15
16
2. The initial position
16
17
17
-
The select function takes a single argument which is the last index position of data returned, and returns a snapshot of the data from the position
18
-
to N amount of rows (here N is up to the function itself).
19
-
20
-
The initial position depends on the context that this pattern is used in, it can be 0, 1, 10 etc.
21
-
18
+
The select function takes a single argument which is the last index
19
+
position of data returned, and returns a snapshot of the data from the
20
+
position to N amount of rows (here N is up to the function itself).
22
21
22
+
The initial position depends on the context that this pattern is used
23
+
in, it can be 0, 1, 10 etc.
23
24
24
25
[source,clojure]
25
26
----
26
27
(defn buffered-select [f-select init-pos]
27
-
"Creates a lazy sequence of messages for this datasource"
(doall (take max (repeatedly #(.readByte raf))))))]
48
+
(with-open [writer (clojure.java.io/writer file)]
49
+
(doseq [x (range 1000)]
50
+
(.write writer x)))
51
+
{:file file :bytes get-bytes}))
65
52
66
53
(def db (load-example))
67
54
68
-
;;normally you'd make the max argument much bigger for performance reasons,
69
-
;;here its set to 5 to show how connecting and querying is done.
55
+
;; Normally you'd make the max argument much bigger for performance reasons,
56
+
;;here its set to 5 to show how connecting and querying is done.
70
57
(defn select [pos] ((:bytes db) pos 5 ) )
71
58
72
59
(def bts (buffered-select select 0))
@@ -78,13 +65,19 @@ You can explore the usage of this recipe by going through a simple file reading
78
65
79
66
==== Discussion
80
67
81
-
The solution showed is a simple pattern (monad) with simple constructs, and its usage applies directly to database queries and network io,
82
-
and more generally to all resources that are accessed using a connection or resource interface (as shown in the example).
83
-
84
-
The select function connects (opens a file), queries (sees to the position and reads max amount of bytes) and closes a connection (closes the file), then returns a sequence.
85
-
The sequence can then be consumed by the using code and after the buffer has been consumed the select function is called again. To the user of the function it appears as if the sequence is
86
-
one huge sequence over which higher order functions like map filter partition can be applied.
87
-
88
-
The pattern also helps unroll the typical with-open pattern; where work must be done inside the scope of another function and cannot be pulled, to something more pull orientated and functional.
89
-
90
-
68
+
The solution showed is a simple pattern (monad) with simple
69
+
constructs, and its usage applies directly to database queries and
70
+
network io, and more generally to all resources that are accessed
71
+
using a connection or resource interface (as shown in the example).
72
+
73
+
The select function connects (opens a file), queries (sees to the
74
+
position and reads max amount of bytes) and closes a connection
75
+
(closes the file), then returns a sequence. The sequence can then be
76
+
consumed by the using code and after the buffer has been consumed the
77
+
select function is called again. To the user of the function it
78
+
appears as if the sequence is one huge sequence over which higher
79
+
order functions like map filter partition can be applied.
80
+
81
+
The pattern also helps unroll the typical with-open pattern; where
82
+
work must be done inside the scope of another function and cannot be
83
+
pulled, to something more pull orientated and functional.
0 commit comments