wtorek, grudnia 18, 2012

Tuning GFS2

echo 2048 > /sys/kernel/config/dlm/cluster/lkbtbl_size
echo 2048 > /sys/kernel/config/dlm/cluster/rsbtbl_size
echo 2048 > /sys/kernel/config/dlm/cluster/dirtbl_size

czwartek, grudnia 13, 2012

BW parallel processing

Long lasting activities are put into spawned processes. Spawned processes share responses via Wait/Notify BW mechanism. Schema for response is a choice of all results/errors from all called activities. First wait can get response from any spawned process, the same if for subsequent Wait calls.

How to make compensations for this kind of process? Subprocess after failed notify should revert its actions, main process does necessery waiting and responds to client with success or error, when from first wait we get fatal error which should break other subprocess call, we do not wait for other calls - they will be reverted.

poniedziałek, grudnia 10, 2012

__caret_closure_caret_ i __caret_userClosure_caret_

Wywołania adapterowe Tibco BW zawierają pola __caret_closure_caret_ i __caret_userClosure_caret_. Pola te z założenia są generyczne i przeznaczone do adapterów każdego typu, ale mogą przenosić informacje sterujące adaptera konkretnego typu. W Tibco Designerze te elementy widoczne są bez ściśle określonego typu XSD. W przypadku adaptera SAP R/3 w większości przypadków nie należy się klauzurkami przejmować, póki nie zawierają parametrów kontrolujących wywołania RFC. Element __caret_closure_caret_ powinien być rzutowany i przepisywany jako binary/base64, zaś __caret_userClosure_caret_ powinien mieć koercję do AESchemas/ae/SAPAdapter40/classes/RFCCLOSURE.

Wykrywanie kodowania znaków w requescie HTTP

String acceptCharset = request.getHeader(ACCEPT_CHARSET);
Charset charset = getBestCharset(acceptCharset!=null ? acceptCharset :
 getCharsetFromContentType(request.getHeader(CONTENT_TYPE), content));
  
    private static Charset getBestCharset(String acceptCharset) {
        if (acceptCharset==null)
            return CharsetUtil.UTF_8;
        StringTokenizer st = new StringTokenizer(acceptCharset, ",");
        while (st.hasMoreTokens()) {
            try {
                return Charset.forName(st.nextToken().trim());
            }
            catch (Exception exc) {};
        }
        return CharsetUtil.UTF_8;
    }
 
    private static String getCharsetFromContentType(String ct, ChannelBuffer data) {
        ct = ct!=null ? ct.toLowerCase() : "";
        int charsetPos = ct.indexOf("charset=");
        if (charsetPos!=-1) {
            for (int i=charsetPos+8; i < ct.length(); i++) {
                if (!Character.isLetterOrDigit(ct.charAt(i))) {
                    return ct.substring(charsetPos+8, i);
                }
            }
        }
        if (data!=null) {
            int win1250_score = 0;
            int iso8859_2_score = 0;
            for (int i=0; i < data.readableBytes(); i++) {
                int b = (data.getByte(i) & 0xff);
                if (b == '%') {
                    if (i+2 < data.readableBytes()) {
                        try {
                            b = Integer.rotateLeft(getHex(data.getByte(i+1)), 4) + getHex(data.getByte(i+2));                           
                        }
                        catch (Exception parseExc) {}
                    }
                }
                for (int k=0; k < WIN1250.length; k++) {
                    if (b == WIN1250[k])
                        win1250_score++;
                    else if (b == ISO_8859_2[k])
                        iso8859_2_score++;
                }
            }
            System.out.println(win1250_score+"/"+iso8859_2_score);
            if (win1250_score > 0 && win1250_score >= iso8859_2_score)
                return "windows-1250";
            if (iso8859_2_score > 0 && iso8859_2_score >= win1250_score)
                return "iso-8859-2";
        }
        return null;
    }
 
    private final static int getHex(byte b) {
        int c = b & 0xff;
        if (c >= '0' && c <= '9')
            return c-'0';
        if (c >= 'a' && c <= 'f')
            return 10+c-'a';
        if (c >= 'A' && c <= 'F')
            return 10+c-'A';
        throw new RuntimeException("Char "+c+" is not valid hex");
    }
 
    /* ąśźĄŚŹ */
    private final static int WIN1250[] = { 185,156,159,165,140,143 };
    private final static int ISO_8859_2[] = { 177,182,188,161,166,172 };

piątek, grudnia 07, 2012

Kradzież kodu: T-Mobile obwinia Software Mind

Szanowny Panie,
Bardzo dziękujemy za zawrócenie uwagi PTC na problem związany z produktem dostarczanym przez jednego z naszych dostawców, firmę Software Mind SA, z siedzibą przy ul. Bociana 22A w Krakowie (dalej "Software Mind").
Jako firma ceniąca sobie etyczne działania w biznesie, dzięki Pana informacjom rozpoczęliśmy wewnętrzny proces wyjaśnień z dostawcą.

Chcielibyśmy jednocześnie zaznaczyć, że jakiekolwiek dalsze kwestie, związane z wykorzystaniem przez firmę Software Mind Pańskiej własności intelektualnej powinien Pan kierować bezpośrednio do rzeczonej firmy.

Pozdrawiam,
Piotr Chmiel

Kierownik, Dział Zarządzania Zgodnością
Polska Telefonia Cyfrowa S.A.

czwartek, grudnia 06, 2012

Tibco BW FlowLimit


FlowLimit jest zaimplementowany w taki sposób, że po jego przekroczeniu wyłączany jest starter (onStop) aż do momentu, kiedy zwolnią się wszystkie wątki obsługujące proces startera. Jeśli FlowLimit wynosi 20 a podłączonych jest 30 klientów, którzy ciągle wywołują jednowątkowo usługę SOAP over HTTP, to 10 klientów będzie obserwowało długi czas połączenia, odmowę połączenia (connection refused) lub błąd HTTP 503 Service Unavailable. Czekanie na zwolnienie wszystkich wątków wykonawczych jak i różne zachowania przy odrzucaniu żądania (w dodatku bez jakiegokolwiek śladu w logach BW!) budzą zastrzeżenia. Proces obsługi żądania powinien sprawdzać stan nasycenia puli wykonawczej i jeśli nie jest ona pełna pozwalać na stworzenie eventu BW i w rezultacie wykonanie procesu. Jeśli kolejka oczekujących żądań jest zbyt długa i nie maleje, to wykraczający poza limit komunikat powinien być szybko odrzucany. Oryginalna implementacja Tibco tak ładnie się nie zachowuje, wyraźnie widoczna jest czkawka. Całe szczęście własny Java Event Starter pozwala na stworzenie własnych bardziej deterministycznych lekkich usług, w których dbamy o opóźnienia, przepustowość i niezawodność.

poniedziałek, grudnia 03, 2012

Denial of Service attack against Tibco EMS

In a loop with every iteration create 50 000 producers on one session and then close it. On session close server will be deleting information about session from metadb and this activity will slow down whole server causing massive timeouts. It will be impossible to access services hosted on EMS.

sobota, grudnia 01, 2012

HornetQAIO64.dll

Sportowałem na szybko libhornetqaio64.so pod 64-bitowe Windows. Binarka jest dla serwera 2.2.14. Przy odrobinie konsekwencji da się zmapować API jeden do jednego. Asynchroniczne operacje I/O dają serwerowi JMS HornetQ duży wzrost wydajności na Linuksie.