EzDev.org

aleph

asynchronous communication for clojure aleph


Compojure/Ring Routing Error: Wrong # of Arguments

The route setup detailed below causes the error: Wrong number of args (0) passed to: PersistentArrayMap Can anyone help me understand this error and how to resolve it?

(defn sign-in [req]
  ({:status 200 :body "hello world" :headers {"content-type" "text/plain"}})) 

(defroutes paths
  (GET "/connect" {} connect-socket)
  (POST "/sign-in" {} sign-in)
  (route/resources "/")
  (route/not-found "Resource not found."))

(def app
  (-> (defaults/wrap-defaults #'paths defaults/api-defaults)
      wrap-json-params))

Source: (StackOverflow)

Compiling Yap on windows 8

I am trying to compile yap on my PC since it seems YAP default installers don't come with the Depth limit flag enabled. I need this to work on an ILP project on Aleph.

The thing is, that I am forced to use a PC with windows 8 without enough memory for a Linux Virtual machine. I got cygwin to attempt to install it, but once I get to the 'make' stage of the installation ( http://www.dcc.fc.up.pt/~vsc/Yap/Yap4.3/yap.html#SEC2 ) I get this following error

$ make
Makefile:714: warning: overriding recipe for target 'yap.dll'
Makefile:545: warning: ignoring old recipe for target 'yap.dll'
gcc  -mno-cygwin -c -O3 -fomit-frame-pointer -Wall -Wstrict-prototypes -Wmissing-prototypes -g -O2 -DCUT_C=1  -DCOROUTINING=1 -DRATIONAL_TREES=1 -DDEPTH_LIMIT=1 -DHAVE_CONFIG_H -D_YAP_NOT_INSTALLED_=1 -I. -I../H -I../OPTYap -I../BEAM -I../MYDDAS ../C/agc.c -o agc.o
gcc: error: unrecognized command line option ‘-mno-cygwin’
Makefile:488: recipe for target 'agc.o' failed
make: *** [agc.o] Error 1

I assume it's due to the latest YAP being outdated right now, does anyone know what to do to work around this?


Source: (StackOverflow)

Handling websocket client messages with aleph

During my quest to learn Clojure I am currently facing problems with setting up websocket communitation. After many different approaches, I ended up using aleph.

What I managed to achieve:

  • handling of a new client connecting
  • handling a client disconnection
  • talking from the server to clients at will

What I lack is means to trigger a handler function whenever one of the connected clients sends something via the websocket.

My code so far:

(ns wonders7.core.handler
  (:require [compojure.core :refer :all]
            [compojure.route :as route]
            [ring.middleware.defaults :refer [wrap-defaults site-defaults]]
            [aleph.http :as http]
            [manifold.stream :as stream]
            [clojure.tools.logging :refer [info]]))

(defn uuid [] (str (java.util.UUID/randomUUID)))

(def clients (atom {}))

(defn ws-create-handler [req]
  (let [ws @(http/websocket-connection req)]
    (info "ws-create-handler")
    (stream/on-closed ws #(swap! clients dissoc ws))
    (swap! clients assoc ws (uuid))))

(defroutes app-routes
  (GET "/ws" [] ws-create-handler)
  (route/not-found "Not Found"))

(def app
  (wrap-defaults app-routes site-defaults))

(defn msg-to-client [[client-stream uuid]]
  (stream/put! client-stream "The server side says hello!"))

(defn msg-broadcast []
  (map #(msg-to-client %) @clients))

;(stream/take! (first (first @clients)))
;(http/start-server app {:port 8080})

I start the Netty server with the commented out http/start-server aleph call. I also managed to fetch messages from the client via manual stream/take! call (also commented out). What I need to figure out is how to trigger this taking automatically when something comes in.

Thanks in advance for any help!


Source: (StackOverflow)

Failed to find a usable hardware address from the network interfaces

I'm getting the following warning when running Aleph (which uses Netty) as a websever inside a Docker container:

WARNING: Failed to find a usable hardware address from the network interfaces; using random bytes: 75:62:7f:9b:c6:52:63:4b

I'm starting the server using:

(defn -main [& args]
  (http/start-server app {:port 3000}))

And I've also tried:

(defn -main [& args]
  (http/start-server app {:socket-address (java.net.InetSocketAddress. "0.0.0.0" 3000)}))

but still I get the same warning.

The warning only happens inside a docker container. I can run the server in my host without the warning. I also won't get the warning if when I run the container I use docker run --net host webserver.

The really weird thing is, despite the warning everything looks to be running fine. The correct ports are bound and the server is running correctly. Does anyone have any idea why I get this warning?


Source: (StackOverflow)

store Prolog answers to a file

I'm working with ALEPH reasoning engine in SWI-Prolog. I want to save the rules that ALEPH infers and shows them in SWI-Prolog console, but I have no idea how can I do it! The sample result is depicted in the picture below,

[Rule 134] [Pos cover = 1 Neg cover = 0]
likes(u9,soccer).
[Rule 135] [Pos cover = 3 Neg cover = 0]
friends(A,u2) :- age(A,adult).
[Rule 136] [Pos cover = 2 Neg cover = 0]
friends(A,u5) :- age(A,adult).
[Rule 137] [Pos cover = 1 Neg cover = 0]
trusts(u1,u5).
[Rule 138] [Pos cover = 1 Neg cover = 0]
trusts(u5,u7).

these rules are shown after calling the induction procedure with this commands:
- read_all(aleph_files). - induce.

Now I'm wondering how I can store these rules into a txt file automatically.


Source: (StackOverflow)

Async responses with Aleph aren't being received over IPv4 but are with IPv6

I'm trying to get server-sent events set up in Clojure with Aleph, but it's just not working over IPv4. Everything is fine if I connect over IPv6. This occurs both on Linux and MacOS. I've got a full example of what I'm talking about on GitHub.

I don't think I'm doing anything particularly fancy. The whole code is up on GitHub, but essentially my program is:

(def my-channel (permanent-channel))

(defroutes app-routes
  (GET "/events" []
    {:headers {"Content-Type" "text/event-stream"}
     :body my-channel}))

(def app
  (handler/site app-routes))

(start-server (wrap-ring-handler app) {:port 3000}))

However, when I connect to 127.0.0.1:3000, I can see curl sending the request headers, but it just hangs, never printing the response headers:

$ curl -vvv http://127.0.0.1:3000/events

* About to connect() to 127.0.0.1 port 3000 (#0)
*   Trying 127.0.0.1...
* Adding handle: conn: 0x7f920a004400
* Adding handle: send: 0
* Adding handle: recv: 0
* Curl_addHandleToPipeline: length: 1
* - Conn 0 (0x7f920a004400) send_pipe: 1, recv_pipe: 0
* Connected to 127.0.0.1 (127.0.0.1) port 3000 (#0)
> GET /events HTTP/1.1
> User-Agent: curl/7.30.0
> Host: 127.0.0.1:3000
> Accept: */*

If I connect over IPv6 the response comes right away, and events that I enqueue in the channel get sent correctly:

$ curl -vvv http://localhost:3000/events

* Adding handle: conn: 0x7f943c001a00
* Adding handle: send: 0
* Adding handle: recv: 0
* Curl_addHandleToPipeline: length: 1
* - Conn 0 (0x7f943c001a00) send_pipe: 1, recv_pipe: 0
* About to connect() to localhost port 3000 (#0)
*   Trying ::1...
* Connected to localhost (::1) port 3000 (#0)
> GET /events HTTP/1.1
> User-Agent: curl/7.30.0
> Host: localhost:3000
> Accept: */*
>
< HTTP/1.1 200 OK
* Server aleph/0.3.0 is not blacklisted
< Server: aleph/0.3.0
< Date: Tue, 15 Apr 2014 12:27:05 GMT
< Connection: keep-alive
< Content-Type: text/event-stream
< Transfer-Encoding: chunked

I have also reproduced this behaviour in Chrome. In both the IPv4 and IPv6 cases, tcpdump shows that the response headers are going over the wire.

This behaviour occurs both with lein run and an uberjar. It also occurs if I execute the uberjar with -Djava.net.preferIPv4Stack=true.

How do I get my application to behave the same over IPv4 as over IPv6?


Source: (StackOverflow)

NullPointerException when lein ring server on Aleph+Ring

I am trying to run Aleph on top of Ring and use lein ring server for shorter feedback loop.

When I'm invoking lein ring server everything seems to be fine but when I point my browser to an url I get a nasty NullPointerException with the stack trace below.

However, when I run (al.app/start 3006) then no NLP shows up.

The whole project is available on GitHub.

What am I doing wrong?

core.clj:107    lamina.core/enqueue
app.clj:39  al.app/hello-handler
http.clj:79 aleph.http/wrap-aleph-handler[fn]
response.clj:27 compojure.response/eval1328[fn]
response.clj:10 compojure.response/eval1289[fn]
core.clj:93 compojure.core/make-route[fn]
core.clj:39 compojure.core/if-route[fn]
...    

I am using aleph 0.3.2 and that's my code:

(ns al.app
  (:use
      aleph.http
      lamina.core
      compojure.core
      ring.middleware.keyword-params)
 (:require [compojure.route :as route]))

(defn hello-handler                                                                    
  "Our handler for the /hello path"                                                    
  [ch request]                                                                         
  (let [params (:route-params request)                                          
        name (params :name)]                                                           
    (enqueue ch                                                                        
      {:status 200                                                                     
       :headers {}                                                                     
       :body (str "Hello " name)})))                                                   

(defroutes my-routes                                                                   
  (GET ["/hello/:name", :name #"[a-zA-Z]+"] {} (wrap-aleph-handler hello-handler))     
  (route/not-found "Page not found"))                                                  

(defn start                                                                            
    "Start our server in the specified port"                                           
    [port]                                                                             
    (start-http-server (wrap-ring-handler my-routes) {:port port})) 

Source: (StackOverflow)