2015-12-21 6 views
6

Najwyraźniej nie do zlekceważenia błąd podczas bawiąc się z Rebol/Core (278-3-1), aby rodzaj serwera internetowego do obsługi tekstu statycznego, zawierającego link przekierowania do nowej lokalizacji usługi.Debuguj i unikaj okresowego błędu REBOL2, który próba [] nie powoduje (?) Przechwycenia?

Specyficzne położenie błędu wydaje się być w kodzie przykładowym napisanym przez samego siebie w roku Carl Sassenrath, więc jestem trochę zaskoczony, że po tych wszystkich latach może pojawić się niewykryty błąd.

Mam trzy z tych skryptów działających jednocześnie, monitorowanie trzech pojedynczych portów. Zasadniczo skrypt działa tak, jak powinien ... kiedy dostęp do niego odbywa się kilkakrotnie (na wszystkich skryptach równoległych), wydaje się, że jest dość stabilny ... ale jeden po drugim zawodzi. Czasami po 2 minutach, czasami po 20 minutach - po dodaniu oświadczenia drukowania czasami nawet po 60 minutach - ale ostatecznie nie uda im tak:

** Script Error: Out of range or past end
** Where: forever
** Near: not empty? request: first http-port

Próbowałem owijania tylko o każdą część programu w pętli a try [] [wyjątek], ale błąd nadal występuje. Niestety, moja wyszukiwarka okazuje się słaba o tej porze roku, ponieważ nie znalazłem niczego, co mogłoby wyjaśnić problem.

Kod jest wycięte wersja Carl Sassenrath na Tiny Web Server, nieznacznie zmodyfikowane, aby wiązać się z określonym IP i emitować HTML zamiast plików ładowania:

REBOL [title: "TestMovedServer"] 
AppName: "Test" 
NewSite: "http://test.myserver.org" 

listen-port: open/lines tcp://:81 browse http://10.100.44.6? 
buffer: make string! 1024 ; will auto-expand if needed 

forever [ 
    http-port: first wait listen-port 
    clear buffer 

    while [not empty? request: first http-port][ 
     print request 
     repend buffer [request newline] 
     print "----------" 
    ] 
    repend buffer ["Address: " http-port/host newline] 
    print buffer 
    Location: "" 
    mime: "text/html" 
    parse buffer ["get" ["http" | "/ " | copy Location to " "]] 

    data: rejoin [{ 
     <HTML><HEAD><TITLE>Site Relocated</TITLE></HEAD> 
     <BODY><CENTER><BR><BR><BR><BR><BR><BR> 
     <H1>} AppName { have moved to <A HREF="} NewSite {">} NewSite {</A></H1> 
     <BR><BR><BR>Please update the link you came from. 
     <BR><BR><BR><BR><BR><A HREF="} NewSite Location {">(Continue directly to the requested page)</A> 
     </CENTER></BODY></HTML> 
    }] 
    insert data rejoin ["HTTP/1.0 200 OK^/Content-type: " mime "^/^/"] 
    write-io http-port data length? data 
    close http-port 
    print "============" 
] 

Czekam, aby zobaczyć to, czego faceci to robią!

Odpowiedz

3

Otrzymujesz błąd podczas próby odczytu z zamkniętego połączenia. To wydaje się działać.

n: 0 
forever [ 
    http-port: first wait listen-port 
    clear buffer 
    if attempt [all [request: first http-port not empty? request]] [ 
     until [ 
     print request 
     repend buffer [request newline] 
     print "----------" 
     any [not request: first http-port empty? request] 
     ] 
     repend buffer ["Address: " http-port/host newline] 
     print buffer 
     Location: "" 
     mime: "text/html" 
     parse buffer ["get" ["http" | "/ " | copy Location to " "]] 

     data: rejoin [{ 
     <HTML><HEAD><TITLE>Site Relocated</TITLE></HEAD> 
     <BODY><CENTER><BR><BR><BR><BR><BR><BR> 
     <H1>} AppName n: n + 1 { has moved to <A HREF="} NewSite {">} NewSite {</A></H1> 
     <BR><BR><BR>Please update the link you came from. 
     <BR><BR><BR><BR><BR><A HREF="} NewSite Location {">(Continue directly to the requested page)</A> 
     </CENTER></BODY></HTML> 
     }] 
     insert data rejoin ["HTTP/1.0 200 OK^/Content-type: " mime "^/^/"] 
     write-io http-port data length? data 
    ] 
    attempt [close http-port] 
    print "============" 
] 
+0

Dziękuję sqlab. – fsteff

+0

Chcesz wyjaśnić, w jaki sposób doszliśmy do wniosku, że oryginalny kod był czytany z zamkniętego połączenia? Należy docenić kroki debugowania. – fsteff

+0

Wniosek pochodzi z mieszanki rozważań i prób i dużej ilości doświadczeń. – sqlab

1

Zobaczmy dokumentację dla pustych? Podsumowanie:

Zwraca wartość PRAWDA, jeśli seria jest na ogonie. Użycie:

pusty? seria Argumenty: seria

- Argument serii. (musi być: bitset portu szeregowego)

Tak pusty? wymaga argumentu szeregowego, portowego lub bitsetowego lub łańcuchowego. Twoja zmienna (request) otrzymuje jeden z nich, dopóki jest otwarte połączenie z portem. pusty? może następnie określić, czy znajduje się na końcu zmiennej. Gdy połączenie jest zamknięte/przerwane, zmienna nie otrzymuje nic, ale błąd dostępu łączy się z portem. Błąd nie ma ogona. pusty? zostaje pomieszany i zawiesza się z błędem.

sqlab zastąpił pusty? z próbą

if attempt [all [request: first http-port not empty? request]] 

Funkcja PRÓBA jest skrót do częstego przypadku:

error? try [block] 

z wszystko on strzeże przed błędem, jak również brak. ATTEMPT zwraca wynik bloku, jeśli błąd nie wystąpił. Jeśli wystąpił błąd, zwracana jest wartość NONE. również z i

any [not request: first http-port empty? request] 

on pilnuje przeciwko obu.

Dlatego jego kod działa.

+0

Dziękuję za doskonałą i bardzo edukacyjną odpowiedź. Dokładnie to rozumowanie, na które liczyłem. – fsteff

Powiązane problemy