I want to test a method which takes a callback. The callback is then executed via deferred at some later point. I have
(describe
"Nimsuggest"
(it "should suggest on a simple file"
(with-current-buffer (find-file "tests/nimsuggest/simple.nim")
(expect (nim-call-epc 'sug callback)))))
but I'm not sure what to use as the testing callback.
Related
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.
By reading some text, especially the iOS document about delegate, all the protocol method are called hook that the custom delegate object need to implement. But some other books, name these hook as callback, what is the difference between them? Are they just different name but the same mechanism? In addition to Obj-C, some other programming languages, such as C, also got the hook, same situation with Obj-C?
The terminology here is a bit fuzzy. In general the two attempt to achieve similar results.
In general, a callback is a function (or delegate) that you register with the API to be called at the appropriate time in the flow of processing (e.g to notify you that the processing is at a certain stage)
A hook traditionally means something a bit more general that serves the purpose of modifying calls to the API (e.g. modify the passed parameters, monitor the called functions). In this meaning it is usually much lower level than what can be achieved by higher-level languages like Java.
In the context of iOS, the word hook means the exact same thing as callback above
Let me chime in with a Javascript answer. In Javascript, callbacks, hooks and events are all used. In this order, they are each higher level concepts than the other.
Unfortunately, they are often used improperly which leads to confusion.
Callbacks
From a control flow perspective, a callback is a function, usually given as an argument, that you execute before returning from your function.
This is usually used in asynchoronous situations when you need to wait for I/O (e.g. HTTP request, a file read, a database query etc.). You don't want to wait with a synchronous while loop, so other functions can be executed in the meantime.
When you get your data, you (permanently) relinquish control and call the callback with the result.
function myFunc(someArg, callback) {
// ...
callback(error, result);
}
Because the callback function may be some code that hasn't been executed yet, and you don't know what's above your function in the call stack, generally instead of throwing errors you pass on the error to the callback as an argument. There are error-first and result-first callback conventions.
Mostly callbacks have been replaced by Promises in the Javascript world and since ES2017+, you can natively use async/await to get rid of callback-rich spaghetti code and make asynchronous control flow look like it was synchronous.
Sometimes, in special cascading control flows you run callbacks in the middle of the function. E.g. in Koa (web server) middleware or Redux middleware you run next() which returns after all the other middlewares in the stack have been run.
Hooks
Hooks are not really a well-defined term, but in Javascript practice, you provide hooks when you want a client (API/library user, child classes etc.) to take optional actions at well-defined points in your control flow.
So a hook may be some function (given as e.g. an argument or a class method) that you call at a certain point e.g. during a database update:
data = beforeUpdate(data);
// ...update
afterUpdate(result);
Usually the point is that:
Hooks can be optional
Hooks usually are waited for i.e. they are there to modify some data
There is at most one function called per hook (contrary to events)
React makes use of hooks in its Hooks API, and they - quoting their definition - "are functions that let you “hook into” React state and lifecycle features", i.e. they let you change React state and also run custom functions each time when certain parts of the state change.
Events
In Javascript, events are emitted at certain points in time, and clients can subscribe to them. The functions that are called when an event happens are called listeners - or for added confusion, callbacks. I prefer to shun the term "callback" for this, and use the term "listener" instead.
This is also a generic OOP pattern.
In front-end there's a DOM interface for events, in node.js you have the EventEmitter interface. A sophisticated asynchronous version is implemented in ReactiveX.
Properties of events:
There may be multiple listeners/callbacks subscribed (to be executed) for the same event.
They usually don't receive a callback, only some event information and are run synchronously
Generally, and unlike hooks, they are not for modifying data inside the event emitter's control flow. The emitter doesn't care 'if there is anybody listening'. It just calls the listeners with the event data and then continues right away.
Examples: events happen when a data stream starts or ends, a user clicks on a button or modifies an input field.
The two term are very similar and are sometimes used interchangably. A hook is an option in a library were the user code can link a function to change the behavior of the library. The library function need not run concurrent with the user code; as in a destructor.
A callback is a specific type of hook where the user code is going to initiate the library call, usually an I/O call or GUI call, which gives contol over to the kernel or GUI subsystem. The controlling process then 'calls back' the user code on an interupt or signal so the user code can supply the handler.
Historically, I've seen hook used for interupt handlers and callback used for GUI event handlers. I also see hook used when the routine is to be static linked and callback used in dynamic code.
Two great answers already, but I wanted to throw in one more piece of evidence the terms "hook" and "callback" are the same, and can be used interchangeably: FreeRTOS favors the term "hook" but recognizes "callback" as an equivalent term, when they say:
The idle task can optionally call an application defined hook (or callback) function - the idle hook.
The tick interrupt can optionally call an application defined hook (or callback) function - the tick hook.
The memory allocation schemes implemented by heap_1.c, heap_2.c, heap_3.c, heap_4.c and heap_5.c can optionally include a malloc() failure hook (or callback) function that can be configured to get called if pvPortMalloc() ever returns NULL.
Source: https://www.freertos.org/a00016.html
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!
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)")
Is it a function?
Is it a function being called from the source?
Or, is it a function being returned from the destination?
Or, is it just executing a function at the destination?
Or, is it a value returned from a function passed to the destination?
A callback is the building block of asynchronous processing.
Think of it this way: when you call someone and they don't answer, you leave a message and your phone number. Later on, the person calls you back based on the phone number you left.
A callback works in a similar manner.
You ask an API for a long running operation and you provide a method from within your code to be called with the result of the operation. The API does its work and when the result is ready, it calls your callback method.
From the great Wikipedia:
In computer programming, a callback is
executable code that is passed as an
argument to other code. It allows a
lower-level software layer to call a
subroutine (or function) defined in a
higher-level layer.
Said another way, when you pass a callback to your method, it's as if you are providing additional instructions (e.g., what you should do next). An attempt at making a simple human example follows:
Paint this wall this shade of green (where "paint" is analagous to the method called, while "wall" and "green" are similar to arguments).
When you have finished painting, call me at this number to let me know that you're done and I'll tell you what to do next.
In terms of practical applications, one place where you will sometimes see callbacks is in situations with asynchronous message passing. You might want to register a particular message as an item of interest for class B.
However, without something like a callback, there's no obvious way for class A to know that class B has received the message. With a callback, you can tell class B, here's the message that I want you to listen for and this is the method in class A that I want you to call when you receive it.
Here is a Java example of a callback from a related question.