[isidorus-cvs] r701 - trunk/playground

lgiessmann at common-lisp.net lgiessmann at common-lisp.net
Tue Aug 2 07:54:17 UTC 2011


Author: lgiessmann
Date: Tue Aug  2 00:54:16 2011
New Revision: 701

Log:
trunk: playground: implemented an interface that returns all psis and a json fragment via usocket's tcp-sockets - instead of using hunchentoot

Modified:
   trunk/playground/tcp-connector.lisp

Modified: trunk/playground/tcp-connector.lisp
==============================================================================
--- trunk/playground/tcp-connector.lisp	Mon Aug  1 07:56:39 2011	(r700)
+++ trunk/playground/tcp-connector.lisp	Tue Aug  2 00:54:16 2011	(r701)
@@ -9,8 +9,7 @@
 
 ;; source: http://mihai.bazon.net/blog/howto-multi-threaded-tcp-server-in-common-lisp
 
-(asdf:operate 'asdf:load-op :usocket)
-(asdf:operate 'asdf:load-op :bordeaux-threads)
+(asdf:operate 'asdf:load-op :isidorus)
 
 
 (defun make-server (&key (hostname "localhost") (port 8000))
@@ -71,22 +70,33 @@
   (usocket:socket-close client-socket))
 
 
-(defun task (client-socket mega-loops name)
-  (declare (String name)
-	   (integer mega-loops)
-	   (usocket:stream-usocket client-socket))
-  (let ((loops (* 1000000 mega-loops)))
-    (dotimes (counter loops)
-      (/ (* loops loops) loops))
-    (read-from-client client-socket) ;ignore cient data
-    (send-to-client client-socket (format nil "~a finished ~a loops" name loops))))
+(defvar *stop-listen* nil "if this variable is set to t, the listener stops to listen after the next client has been accepted")
 
 
-(defvar *stop-listen* nil "if tis variable is set to t, te listener stops to listen after the next client is accepted")
+(defun stop-listen-for-clients (server)
+  (setf *stop-listen* t)
+  (usocket:socket-close server)
+  (base-tools:close-tm-store))
 
 
-(defun stop-listen-for-clients ()
-  (setf *stop-listen* t))
+(defun client-task (client-socket)
+  (declare (usocket:stream-usocket client-socket))
+  (handler-case
+      (let ((client-data (read-from-client client-socket)))
+	(let ((response
+	       (cond ((string-starts-with (first (getf client-data :headers))
+					  "GET /json/psis")
+		      (get-psis))
+		     ((string-starts-with (first (getf client-data :headers))
+					  "GET /json/get/")
+		      (get-fragment (get-requested-psi-of-http-header
+				     (first (getf client-data :headers)))))
+		     (t
+		      (concatenate 'string ">> bad request: ~a~%"
+				   (first (getf client-data :headers)))))))
+	  (send-to-client client-socket response)))
+    (condition ()
+      (usocket:socket-close client-socket))))
 
 
 (defun listen-for-clients (server)
@@ -99,14 +109,78 @@
 		  (let ((client (wait-for-client srv)))
 		    (format t "client # ~a connected~%" counter)
 		    (sb-thread:make-thread
-		     (lambda()
-		       (funcall (lambda(client-socket thread-name)
-				  (declare (usocket:stream-usocket client-socket)
-					   (String thread-name))
-				  (read-from-client client-socket) ;ignore client data
-				  (send-to-client client-socket thread-name))
-				client (format nil "thread-~a" counter)))
+		     (lambda() (funcall #'client-task client))
 		     :name (format nil "worker-thread: ~a" counter)))
 		  (incf counter)
 		  (setf stop-p *stop-listen*)))
-	      server))))
+	      server))
+   :name "server-listener"))
+
+
+(defun get-psis ()
+  (isidorus-threading:with-reader-lock
+    (json-exporter:get-all-topic-psis :revision 0)))
+
+
+(defun get-fragment(psi)
+  (let ((fragment (isidorus-threading:with-reader-lock
+		    (d:get-latest-fragment-of-topic psi))))
+    (if (and fragment
+	     (d:find-item-by-revision (d:topic fragment) 0))
+	(json-exporter:export-construct-as-isidorus-json-string fragment :revision 0)
+	(concatenate 'string psi " not found"))))
+	  
+
+(defun get-requested-psi-of-http-header (first-header-line)
+  (declare (String first-header-line))
+  (when (and (string-starts-with first-header-line "GET /json/get/")
+	     (or (string-ends-with first-header-line "HTTP/1.0")
+		 (string-ends-with first-header-line "HTTP/1.1")))
+    (let ((psi (subseq first-header-line
+		       (length "GET /json/get/")
+		       (- (length first-header-line) (length "HTTP/1.0")))))
+      (hunchentoot:url-decode (string-trim '(#\space) psi)))))
+    
+
+(defun string-starts-with (str prefix &key (ignore-case nil))
+  "Checks if string str starts with a given prefix."
+  (declare (String str prefix)
+	   (Boolean ignore-case))
+  (let ((str-i (if ignore-case
+		   (string-downcase str :start 0 :end (min (length str)
+							   (length prefix)))
+		   str))
+	(prefix-i (if ignore-case
+		      (string-downcase prefix)
+		      prefix)))
+    (string= str-i prefix-i :start1 0 :end1
+	     (min (length prefix-i)
+		  (length str-i)))))
+
+
+(defun string-ends-with (str suffix &key (ignore-case nil))
+  "Checks if string str ends with a given suffix."
+  (declare (String str suffix)
+	   (Boolean ignore-case))
+  (let ((str-i (if ignore-case
+		   (string-downcase str :start (max (- (length str)
+						       (length suffix))
+						    0)
+				    :end (length str))
+		   str))
+	(suffix-i (if ignore-case
+		      (string-downcase suffix)
+		      suffix)))
+    (string= str-i suffix-i :start1 (max (- (length str)
+					    (length suffix))
+					 0))))
+
+
+(defun main()
+  (format t ">> entered (main)")
+  (base-tools:open-tm-store "/home/lukas/.sbcl/site/isidorus/trunk/src/data_base")
+  (defvar *server* (make-server :port 8080))
+  (listen-for-clients *server*))
+
+
+(main)
\ No newline at end of file




More information about the Isidorus-cvs mailing list