I'm looking to do some synchronous web-programming in Common Lisp, and I'm rounding up options. One of them is sw-http, an "HTTP server tailored for AJAX/Comet". The documentation seems to be a bit lacking because the only piece I could find tells you to
Sub-class SERVER and set the APPLICATION-FINDER-FN slot to a callback
that generates your content.
There doesn't seem to be any notes or examples about what that callback should look like (some prodding told me that it should expect a server and a connection as arguments, but nothing about what it should return or do).
setting it to something naive like
(lambda (server conn) (declare (ignore server conn)) "Hello world")
doesn't seem to do anything, so I assume I either need to write to a stream somewhere or interact with the server/connection in some less-than-perfectly-obvious way.
Any hints?
The handler takes a connection which has a response which has some chunks.
Presumably you're to add your content to the chunks (which are octets) of the response of the connection. Luckily there are some helper methods defined to make this easier.
You might try this (I couldn't get SW-HTTP to compile so I can't):
(defun hello (server connection)
(let*((response (cn-response connection))
(chunks (rs-chunks response)))
(queue-push chunks
(mk-response-status-code 200)
(queue-push chunks
(mk-response-message-body "Hello cruel world"))))
(defclass my-server (server)
((application-finder-fn :initform #'hello)))
Good luck!
Related
I started writing web-apps and distributed apps when REST was already popular, so I actually never used RPC.
When searching for a simple explanation of the difference between them, I started to understand, but some examples got me confused.
I saw things like this:
GET /getLastUser
or this:
POST /changeUserName
If REST is meant for resources, and RPC is meant for procedures, isn't it a bad practice using RPC for something like this?
Correct me if I'm wrong, but the way I see it, RPC should be more purely functional.
Meaning that calling a procedure should always:
return the same result for the same arguments
not affect state
So, RPC calls like this:
GET /addTwo?num=5
that return something like this:
{
"result": 7
}
seem more logical to me (although that's a very simple example).
If this question gets closed for being too "opinion-based", I'll just know that I should do whatever the heck I want...
RPC is not meant to be functional. Calling a same procedure twice gives no guarantee about the result.
This question can be answered a few different ways, and pretty deep. I think this might be a fair summary.
With RPC the primitives typically are function names, arguments and results.
With REST the primitive is a 'resource representation'.
So where with RPC you might call a function, in REST you are really sending and retrieving the state of a resource, regardless of protocol.
This means you typically only ask a server 'can you give me the state of this resource', or you tell a server 'here's a new resource state, please store it at this location'. The only successful answers REST will give are "the current state" or "this operation worked", but with RPC the question (function + arguments) and answer (the result) can be anything.
So you can argue that when you describe it like this, RPC is a lot more flexible. It probably is, but because REST confines itself to just transmitting state, you gain a lot of guarantees that a simple RPC-based protocol does not give.
REST is not just about transferring state. The usage hyper-links is another important requirement for a service to be called REST, and this is also something that you don't get 'out of the box' with RPC.
Lastly, it can be argued that HTTP itself is an RPC-like protocol. I think it's possible to build a RESTful service on top of any RPC service.
using ccl specifically, I am trying to set up two sockets in the same program to serve as a fifo data structure.
to that end, I've been standing up test code to exercise my understanding of the api, and I now have a problem I can't figure out. The following code snipped sets up two sockets, one listen and one to connect to the listen, and accepts the connection on the listen socket (the accept call waits for a connection to come in before returning, which is what I want in this case), after which we write to one socket and read from the other. the code hangs and I don't know why (I assume its because the sockets aren't connecting).
The code:
(ccl:with-open-socket (lsock :local-port 8008 :connect :passive :address-family :internet)
(ccl:with-open-socket (tsock :address-family :internet :remote-port 8008 :remote-host "127.0.0.1")
(let ((stream (ccl:accept-connection lsock)))
(write "can you see?" :stream tsock)
(read stream))))
turns out the hang was on the read call, because.... I need (stream-force-output) after the write call. tested and works. Sockets also don't seem to close without explicit calls to (close for lsock, tsock and the stream... I wonder if thats a bug? different question though.
I have inherited a clojure app using the following components:
Jetty server
Compojure
Ring
In order to gain an understanding of the app, I'd like to step through requests.
I'm using Emacs as my IDE.
Is there any tool or techniques I can use to accomplish this ?
Sadly, Clojure doesn't have any readily available step debugger. One can connect to the jvm with jdb and step through the bytecode, but this will not be a direct reflection of your Clojure code (especially thanks to things like laziness, potentially causing certain code to be evaluated from different contexts in the app than the source layout would lead you to expect).
All is not lost though. Because there is a strong focus on using immutible data and pure functions in idiomatic Clojure code, it is straightforward to capture the values of the inputs your functions get at runtime, in order to investigate and / or experiment with new values. For example:
inside your core namespace, you define your handler and launch jetty, and start an nrepl server from the same process:
(ns my-server.core
(:require [ring.middleware
[json :refer (wrap-json-params)]
[multipart-params :refer (wrap-multipart-params)]]
...
[clojure.tools.nrepl.server :as nrepl-server]))
...
(defn init
[]
(when (= (System/getProperty "with_shell") "true")
(nrepl-server/start-server :port 7888))
(run-jetty handler :port 8080))
within a namespace with the code serving a particular request, you can keep track of incoming data in order to use it / investigate it in the repl
(ns my-ns.controllers.home)
(defonce debug (atom []))
(defn home
[request]
(let [in (java.util.Date.)
response (process request)
out (java.util.Date.)]
(swap! debug conj {:in request :out response :fn home :timing [in out]})
response))
Then, from the repl connection you can query the state of my-ns.controllers.hom/debug, by derefing the atom and seeing the various input and output values. This can be generalized to investigate the contents of various intermediate values, whereever you want to track execution. Since the data objects are more often than not immutible, you can have a full record to walk through if you create an atom to store the values. Note that by creating timestamps before and after calculating the request, you can profile the execution of the request handling function's body (which I have abstracted to a single function for clarity here).
There are also libraries like clojure.tools.trace if you want to use print based tracing.
I looked up the dbus package and it seems like all of the functions are built-in to the C source code and there's no documentation for them.
How do I use the dbus-call-method function?
I just had the same problem and found the emacs-fu article that comes up when googling a little too basic for my needs.
In particular I wanted to export my own elisp methods via dbus, and had problems making sense of the dbus terminology and how it applies to the emacs dbus interface.
First thing to check out, the emacs documentation, C-h f dbus-register-method
dbus-register-method is a built-in function in `C source code'.
(dbus-register-method BUS SERVICE PATH INTERFACE METHOD HANDLER)
Register for method METHOD on the D-Bus BUS.
BUS is either the symbol `:system' or the symbol `:session'.
SERVICE is the D-Bus service name of the D-Bus object METHOD is
registered for. It must be a known name.
PATH is the D-Bus object path SERVICE is registered. INTERFACE is the
interface offered by SERVICE. It must provide METHOD. HANDLER is a
Lisp function to be called when a method call is received. It must
accept the input arguments of METHOD. The return value of HANDLER is
used for composing the returning D-Bus message.
BUS is just going to be :session or :system (where you probably almost always want to use :session like a desktop application I suppose).
SERVICE is a unique name for the application on the bus, like an address or domain name. Dbus.el defines dbus-service-emacs as "org.gnu.Emacs".
PATH is to different types of application functionality what SERVICE is to different applications itself. For example a certain emacs module might expose functionality in the /ModuleName PATH under the org.gnu.Emacs SERVICE.
INTERFACE is just like an interface in programming. It is a specification that tells other dbus clients how to communicate with the object(s) your application exposes. It contains for example type signatures for your methods.
So you might have an interface that says something like: under the service org.gnu.Emacs, in the path /ModuleName, you will find a method named helloworld that will take zero arguments and return a string.
The difficult thing to figure out for me was: how do I define an interface for my method?
Poking around dbus.el you'll find that there is dbus-interface-introspectable (among others) defined, that just contains a string "org.freedesktop.DBus.Introspectable", which names a standard interface that just exposes one method:
org.freedesktop.DBus.Introspectable.Introspect (out STRING xml_data)
(link to the spec http://dbus.freedesktop.org/doc/dbus-specification.html#standard-interfaces-introspectable)
And that is the method which is called by clients to find out about what applications expose on the dbus. So we can use that method to look at how other applications advertise their stuff on dbus, and then we can implement our own Introspect method just mimicking what the others are doing and everything will be fine.
Note however that the spec says that applications may implement the Introspectable interface, they don't have to. In fact you can call dbus-register-method just fine with an empty string as interface (anything will do it seems). You will be able to call your method. However I got always NoReply errors and problems with applications hanging waiting for a response from dbus which went away when I figured out how to make my stuff introspectable. So I assume that Introspect() is expected quite often.
So lets do this:
(defun say-world ()
;; you need to map between dbus and emacs datatypes, that's what :string is for
;; if you're returning just one value that should work automatically, otherwise
;; you're expected to put your return values in a list like I am doing here
(list :string "world"))
(dbus-register-method
:session
"org.test.emacs"
"/helloworld"
"org.test.emacs"
"hello"
'say-world)
That is what we want to implement and therefore want to define an interface for (named "org.test.emacs"). You can use it just like that and try to call the hello method with qdbus org.test.emacs /helloworld org.test.emacs.hello. It should work, for me it works only after 20 seconds of waiting (making the application hang), but it works.
Now lets make it introspectable:
(defun dbus-test-slash-introspect ()
"<node name='/'>
<interface name='org.freedesktop.DBus.Introspectable'>
<method name='Introspect'>
<arg name='xml_data' type='s' direction='out'/>
</method>
</interface>
<node name='helloworld'>
</node>
</node>")
(dbus-register-method
:session
"org.test.emacs"
"/"
dbus-interface-introspectable
"Introspect"
'dbus-test-slash-introspect)
(defun dbus-test-slash-helloworld-introspect ()
"<node name='/helloworld'>
<interface name='org.freedesktop.DBus.Introspectable'>
<method name='Introspect'>
<arg name='xml_data' type='s' direction='out'/>
</method>
</interface>
<interface name='org.test.emacs'>
<method name='hello'>
<arg name='' direction='out' type='s' />
</method>
</interface>
</node>")
(dbus-register-method
:session
"org.test.emacs"
"/helloworld"
dbus-interface-introspectable
"Introspect"
'dbus-test-slash-helloworld-introspect)
There we go. We just define two Introspect methods (one for each level of our path hierachy) and return some hand written xml telling other applications about the /helloworld path and the hello method within it. Note that dbus-test-slash-helloworld-introspect contains <interface name="org.test.emacs">...</interface> that has a type signature for our method, that is, as far as I am concerned, the definition of the interface we used when we registered our method with dbus.
Evaluate all that and poke around with qdbus:
~> qdbus org.test.emacs
/
/helloworld
~> qdbus org.test.emacs /
method QString org.freedesktop.DBus.Introspectable.Introspect()
~> qdbus org.test.emacs /helloworld
method QString org.freedesktop.DBus.Introspectable.Introspect()
method QString org.test.emacs.helloworld()
~> qdbus org.test.emacs /helloworld org.test.emacs.hello
world
Hooray, works as expected, no hanging or NoReply errors.
One last thing, you might try to test your method like so:
(dbus-call-method :session "org.test.emacs" "/helloworld" "org.test.emacs" "hello" :timeout 1000)
and find that it just timeouts and wonder why. Thats because if you register and call a method from within the same emacs instance then emacs will wait for itself to answer. There is no fancy threading going on, you will always get a NoReply answer in that situation.
If you have to call and register a method within the same emacs instance you can use dbus-call-method-asynchronously like so:
(defun handle-hello (hello)
(print hello))
(dbus-call-method-asynchronously :session "org.test.emacs" "/helloworld" "org.test.emacs" "hello" 'handle-hello)
Google to the rescue... Follow the link for the example, it's not my code so I won't put it here.
http://emacs-fu.blogspot.com/2009/01/using-d-bus-example.html
Here is a safe way to test for dbus capabilities:
(defun dbus-capable ()
"Check if dbus is available"
(unwind-protect
(let (retval)
(condition-case ex
(setq retval (dbus-ping :session "org.freedesktop.Notifications"))
('error
(message (format "Error: %s - No dbus" ex))))
retval)))
And here is a way to send a dbus notification:
(defun mbug-desktop-notification (summary body timeout icon)
"call notification-daemon method METHOD with ARGS over dbus"
(if (dbus-capable)
(dbus-call-method
:session ; Session (not system) bus
"org.freedesktop.Notifications" ; Service name
"/org/freedesktop/Notifications" ; Service path
"org.freedesktop.Notifications" "Notify" ; Method
"emacs"
0
icon
summary
body
'(:array)
'(:array :signature "{sv}")
':int32 timeout)
(message "Oh well, you're still notified")))
Or, just evaluate the following within Emacs:
(info "(dbus)")
From this rpg socket tutorial we created a socket client in rpg that calls a java server socket
The problem is that connect()/send() operations blocks and we have a requirement that if the connect/send couldn't be done in a matter of a second per say, we have to just log it and finish.
If I set the socket to non-blocking mode (I think with fnctl), we are not fully understanding how to proceed, and can't find any useful documentation with examples for it.
I think if I do connect to a non-blocking socket I have to do select(..., timeout) which tells us if the connect succeed and/ we are able to send(bytes). But, if we send(bytes) afterwards, as it is now a non-blocking socket (which will immediately return after the call), how do I know that send() did the actual sending of the bytes to the server before closing the socket ?
I can fall back to have the client socket in AS400 as a Java or C procedure, but I really want to just keep it in a simple RPG program.
Would somebody help me understand how to do that please ?
Thanks !
In my opinion, that RPG tutorial you mention has a slight defect. What I believe is causing your confusion is the following section's code:
...
Consequently, we typically call the
send() API like this:
D miscdata S 25A
D rc S 10I 0
C eval miscdata = 'The data to send goes here'
C eval rc = send(s: %addr(miscdata): 25: 0)
c if rc < 25
C* for some reason we weren't able to send all 25 bytes!
C endif
...
If you read the documentation of send() you will see that the return value does not indicate an error if it is greater than -1 yet in the code above it seems as if an error has occurred. In fact, the sum of the return values must equal the size of the buffer assuming that you keep moving the pointer into the buffer to reflect what has been sent. Look here in Beej's Guide to Network Programming. You might also like to look at Richard Stevens' book UNIX Network Programming, Volume 1 for really detailed explanations.
As to the problem of determining if the last send before close() did the actual send ... well the paragraph above explains how to determine what portion of the data was sent. However, calling close() will attempt to send all unsent data unless SO_LINGER is set.
fnctl() is used to control blocking while setsockopt() is used to set SO_LINGER.
The abstraction of network communications being used is BSD sockets. There are some slight differences in implementations across OS's but it is generally quite homogeneous. This means that one can generally use documentation written for other OS's for the broad overview. Most of the time.