Mam małą, ale ciężką aplikację CPU w fazie alfa w node.js, jest to mała gra. Występują problemy z wydajnością i muszę przyspieszyć to co najmniej 20 razy, aby przejść do wersji beta. A ponieważ równoległe wykonanie doprowadziłoby mnie bardzo daleko, zdecydowałem, że dobrym początkiem będzie udostępnienie mapy gry pomiędzy procesami lub wątkami, które będą wykonywać na niej operacje równoległe. W węźle nie jest to możliwe, więc postanowiłem napisać mięsiste części w CL (SBCL + Linux) i połączyć się z nim poprzez gniazdo domeny unix.Połącz Node.js jako klienta z serwerem Common Lisp
Plan jest taki:
[players] <-> (node.js front server) <-> (SBCL performing game ticks)
Chodzi o to, muszę zdać szybkich komunikatów pomiędzy node.js i SBCL w materii podobnej do socket.io.
Oto co nie działa (można pominąć tę część)
Na stronie Node, nie mogę używać zwykłego socket.io ponieważ nie obsługuje Unix domeny gniazda, ale moduł net
, więc mogę przynajmniej zrobić socket.write('raw data')
- lepiej niż nic na razie.
Po stronie CL, próbowałem uruchomić woo web server (obsługuje on lokalne gniazda) i mogłem połączyć się z nim z węzła i przekazać surowe dane dookoła, ale są wszystkie niepotrzebne części HTTP zaangażowane i woo zawsze działa jako serwer; to czeka na GET/HTTP/1.1 ....
. Nie znalazłem sposobu, aby zainicjować wiadomość od pierwszego. Ponadto, jest to całkowicie nieudokumentowane i nieczytelne i wymaga wielu wywołań FF do bibliotek C, których w ogóle nie znam.
Więc przeszedłem przez kolejne serwery CL, które się nie skompilowały, nie obsługiwały gniazd Uniksa, zostały porzucone lub nieudokumentowane, ostatecznie przeniesione do zwykłych gniazd sb-bsd, a na końcu do iolib, ale nadal mogę " t wymyślić.
iolib wyglądał obiecująco, ale nie mogę się z nim połączyć z węzła.
mam to:
(with-open-socket (socket :address-family :local
:type :datagram
;; :connect :passive
:local-filename "/tmp/socket")
(format t "Socket created")
;; (listen-on socket)
;; (bind-address socket (make-address "/tmp/socket"))
(loop
(let ((msg (receive-from socket :size 20)))
(format t msg))))
i Dostaję
#<Syscall "recvfrom" signalled error EWOULDBLOCK(11) "Resource temporarily unavailable" FD=6>
[Condition of type IOLIB/SYSCALLS:EWOULDBLOCK]
Restarts:
0: [IGNORE-SYSCALL-ERROR] Ignore this socket condition
1: [RETRY-SYSCALL] Try to receive data again
2: [RETRY] Retry SLIME interactive evaluation request.
3: [*ABORT] Return to SLIME's top level.
4: [ABORT] abort thread (#<THREAD "worker" RUNNING {10055169A3}>)
nie wiem, czy powinienem nazwać coś takiego zaakceptować gniazdkiem lub słuchać na tym, aby najpierw gniazdo. Wszystkie próby spowodowały błędy. Ponadto, jeśli I [RETRY-SYSCALL]
w repl, błąd zniknie na około 10 sekund, ale wraca. W tym czasie węzeł nadal nie może się połączyć.
To wydaje się być bardziej skomplikowane, niż myślałem. Ja już straciłem ~ 6 godzin pracy na iolib sam i nawet nie rozpocznie się parsowania wiadomości, uczenie się, jak tworzyć wydarzenia z nich, konwersja między JSON i s-EXPS etc ..
Moje pytania są:
- w jaki sposób ustawić to połączenie w iolib tak że węzeł na netto można podłączyć?
- Zakładając, że mogę wybrać, jaki typ połączenia najlepiej nadaje się do przekazywania zdarzeń/wiadomości? (datagram/strumień)
- Czy są jakieś narzędzia robocze, których nie próbowałem?
- Czy są też inne biblioteki niż iolib, które są prawdopodobnie bardziej zaawansowane/lepiej udokumentowane?
- Czy są jakieś lepsze/łatwiejsze/szybsze podejścia do tego problemu wydajności/współbieżności?
- Jakieś inne pomysły?
jestem blisko tak wodowania ideę CL i użyć coś w pamięci Mongo z kilku procesów węzłów zamiast (..To nie brzmią naprawdę szybko), ale uwielbiam LISP Byłoby wspaniale mieć takie rzeczy, jak na przykład na zapleczu. Po wczorajszym poranku nie poruszyłem się o cal, po prostu nie mogę wymyślić bibliotek. Być może powinienem nauczyć się clojure.
PS: Normalnie nie prosiłbym o "napisz mi kodu", ale jeśli w pobliżu jest jakaś dobra dusza, byłbym bardzo wdzięczny, nawet w pseudokodach.
PPS: Wszelkie radykalnie różne podejścia są również mile widziane. Proszę, zabierz głos!
Dzięki za przeczytanie!
Masz wiele pytań w tym pytaniu, niektóre związane z Lisp, inne bardziej ogólne (wybierz TCP vs. UDP), więc może być trochę zbyt szeroki. Z drugiej strony twoje pytanie jest interesujące. Jeśli zajdzie taka potrzeba, nie wahaj się, aby w przyszłości umieścić bardziej szczegółowe pytania. Istnieją biblioteki do komunikacji asynchronicznej (cl-async), JSON (cl-json, yason) itp., Które są wystarczająco stabilne. Lepiej byłoby rozwiązać każdy problem osobno, jeden po drugim. Powodzenia. – coredump