Dienstag, 7. Oktober 2014

[linux] SSH-Befehl im Hintergrund ausführen bzw. nicht beenden, wenn die Verbindung abbricht.

Manchmal möchte man im Remote - SSH einen Befehl eingeben, dessen Ausführung ziemlich lange dauern kann. zum Beispiel das Packen vieler Dateien oder weiß der Fuchs was.

Diese Aktion wird Standardmäßig abgebrochen, wenn die SSH Verbindung beendet wird. Das kann zum Beispiel durch den 24h - Reconnect des Providers sein oder irgendeinen anderen Grund haben. In jedem Fall ist das dann sehr ärgerlich.

Man kann das Ganze aber auch im Hintergrund ausführen - mit "screen".

Um genau das Problem zu lösen benutzt man folgenden Befehl:

screen -dmSL myscreen

"myscreen" ist dabei einfach eine Bezeichnung für den geöffneten neuen Screen.

Beendet man nun die Verbindung zum Server, werden die Befehle weiterhin ausgeführt.

[linux] rsync Performance verbessern. Mehr CPU Kerne.

Ich stand vor dem Problem viele kleine (3 Millionen) Bilddateien von einem Server zum anderen kopieren zu müssen, da der Bildauslagerungsserver gewechselt werden sollte.

Das Packen und Archivieren mit tar und gzip war leider unbefriedigend langsam.

Auch die Alternative mit pigz (gzip mit Mehrkern-Unterstützung) brachte keine großartige Besserung.


Syntax für pigz:

 tar -cv –use-compress-program=pigz -f meinarchiv.tar /srv/www/img

Was ich noch nicht probiert habe, ist tar mit einer Erweiterung zu versehen, die mehrere Threads zum Schreiben verwenden kann.

Das gibts hier: http://www.maier-komor.de/mtwrite.html


Syntax für Nutzung mit mtwrite:

mttar xf mytarfile.tar


Ich habe mich dann aber erstmal für die Nutzung von rsync entschieden. Vorteile: Ich muss den laufenden Betrieb (Bildupload) nicht stoppen; Abgebrochene Aktionen können wieder aufgenommen werden; Ich habe nur eine Aktion auszuführen, denn die Daten werden direkt via ssh übertragen.

Leider dauert dieser Vorgang wegen der vielen kleinen Dateien auch ziemlich lange. Nach 24 Stunden waren knapp 70GB übertragen.

Nun gibt es noch einige Dinge die ich demnächst ausprobieren möchte. Und damit ich Sie nicht vergesse gibt es diesen Post :)

Zum Beispiel lässt sich der CPU - Kern den rsync verwendet auf den Maximalwert hochtakten.
Das kann man so machen:

for i in 0 ; do
echo performance > /sys/devices/system/cpu/cpu$i/cpufreq/scaling_governor
done

Mehr dazu auf http://lwn.net/Articles/400489/

Noch etwas mehr verspreche ich mir jedoch von mehreren parallel laufenden rsync- Prozessen.
Mit Hilfe eines Scripts werden die Dateien auf die Prozesse verteilt.

Das Script gibts dort: https://wiki.ncsa.illinois.edu/display/~wglick/Parallel+Rsync

Falls der Link irgendwann mal down sein sollte, hier zum Kopieren:

/bin/bash
# SETUP OPTIONS
export SRCDIR="/folder/path"
export DESTDIR="/folder2/path"
export THREADS="8"
# RSYNC TOP LEVEL FILES AND DIRECTORY STRUCTURE
rsync -lptgoDzd $SRCDIR/ /$DESTDIR/
# FIND ALL FILES AND PASS THEM TO MULTIPLE RSYNC PROCESSES
cd $SRCDIR; find . -type f | xargs -n1 -P$THREADS -I% rsync -az % /$DESTDIR/%
# IF YOU WANT TO LIMIT THE IO PRIORITY, 
# PREPEND THE FOLLOWING TO THE rsync & cd/find COMMANDS ABOVE:
#   ionice -c2

Nachteil hierbei: Bei diesem Script werden alle Dateien des Hauptverzeichnisses mit nur einem Prozess übertragen. In den Kommentaren gab es eine alternative Lösung:

#!/bin/bash
 
# SETUP OPTIONS
export SRCDIR="/Storage/data1"
export DESTDIR="/Storage/data2"
export THREADS="32"
 
# FIND ALL FILES AND PASS THEM TO MULTIPLE RSYNC PROCESSES
cd $SRCDIR
if [[ $? -eq 0 ]]; then
        find . -type d | xargs -I% mkdir -p /$DESTDIR/%
        find . -type f | xargs -n1 -P$THREADS -I% rsync -a % /$DESTDIR/%
fi

Für beide Fälle gilt: Soll per ssh übertragen werden - also von Server zu Server - müssen die rsync Befehle abgeändert werden:

rsync -lptgoDzd -e 'ssh -c arcfour' $SRCDIR/ remotehost:/$DESTDIR/
cd $SRCDIR; find . -type f | xargs -n1 -P$THREADS -I% rsync -az -e 'ssh -c arcfour' % remotehost:/$DESTDIR/%

Und noch ein wichtiger Parameter: Soll das Verzeichnis lediglich geupdated werden und nicht alle Dateien überschrieben werden, unbedingt die Option "-u"verwenden.

Quellen:

http://www.maier-komor.de/mtwrite.html
http://lwn.net/Articles/400489/
https://wiki.ncsa.illinois.edu/display/~wglick/Parallel+Rsync
http://wiki.ubuntuusers.de/rsync


Montag, 19. Mai 2014

Android. App in den Hintergrund, anstatt zu beenden.

statt

finish();

folgenden Code verwenden:

Intent startMain = new Intent(Intent.ACTION_MAIN);
startMain.addCategory(Intent.CATEGORY_HOME);
startMain.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 
startActivity(startMain);
 

Samstag, 17. Mai 2014

Android Webview App. Beim Aufrufen der App bei Klick auf Push Notification wird eine neue Activity erstellt. Fix.

Szenario:

Man hat eine App bzw. in meinem Fall eine Webview App. Per Push erhält man eine Nachricht, dass eine neue Nachricht eingegangen ist. Man klickt nun auf die Push-Notification und anstatt die eventuell vorhandene Activity zu öffnen, wird eine neue Activity gestartet. Das wollte ich gern vermeiden.

Nach echt langer Recherche bin ich dann auf diesen Link gestoßen: http://www.helloandroid.com/tutorials/communicating-between-running-activities

Relevanter Inhalt:

In der Main-Activity:

protected void onNewIntent(Intent intent) {
     super.onNewIntent(intent);
     setIntent(intent);//must store the new intent unless getIntent() will return the old one
       intent = getIntent();
        WebView myWebView = (WebView) findViewById(R.id.webview);
          myWebView.loadUrl(url);
    }

In der Notifiaction Sende Klasse:

Intent intent = new Intent(this, MainActivity.class);
intent.putExtra("tag", tag);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
PendingIntent contentIntent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT);

Donnerstag, 24. April 2014

Höhe und Breite eines HTML Elements mit CSS proportional halten - bei dynamischer Breite/Höhe..

Quelle: http://www.mademyday.de/css-height-equals-width-with-pure-css.html

Mit diesem CSS Trick, bekommt man ein div Element, welches immer die selbe Höhe hat, wie es breit ist.


HTML:
<div class="box">
<div class="content">
Aspect ratio of 1:1</div>
</div>


CSS:
.box{
position: relative;
width: 50%;
}
.box:before{
content: "";
display: block;
padding-top: 100%;
}

In meinem Fall war es nötig einen runden Kreis hinzubekommen bei dynamischer Breite.
(div wird zum kreis mit border-radius:1000px)

Mittwoch, 23. April 2014

HTML Select funktioniert nicht unter Android 2.3. Fix.

Link zum Original-Fix: http://wil.to/android-positioning/

Inhalt, falls der Link irgendwann nicht mehr geht:

"On Android 2.3, a fixed element that contains an absolute positioned element, which itself contains an absolute positioned element, will cause select menus on the page to stop responding altogether.

By removing that nested absolute element (represented by the red square above) the select menu will work normally. Alternately, by removing the fixed positioning of the parent element—either by not disabling user-scalable in one’s viewport tag or by removing the fixed positioning.

Edit: It seems this bug pertains not specifically to nested absolute elements, but to empty absolute elements—including whitespace. By adding a non-breaking space to the nested element, the problem is solved."



Also zum leeren Element einfach ein
<span style='display:none'>&#160;</span>

Mittwoch, 11. April 2012

Javascript dynamisch via Javascript nachladen

Hier http://murksfurtz.blogspot.de/2008/12/mit-ajax-nachgeladene-javascript.html habe ich gezeigt, wie man per Ajax nachgeladenen Javascript-Code ausführbar machen kann.

Eine wahrscheinlich bessere Variante ist es, das Javascript einfach dynamisch in der Hauptdatei via Javascript nachzuladen, denn es sind dann keine Anpassungen an der Syntax des Scripts notwendig und es entfällt auch die Evaluierung, welche je nach Rechenkraft schon etwas Zeit in Anspruch nehmen kann.

Ein Beispiel:

<script type="text/javascript">
function loadScript(scriptname) {
var snode = document.createElement('script');
snode.setAttribute('type','text/javascript');
snode.setAttribute('src',scriptname);
document.getElementsByTagName('head')[0].appendChild(snode);
}
loadScript('../js/benoetigtes_script.js');
</script>


So kann man also Javascript-Funktionen nachladen, die man für neue nachgeladene Ajax-Inhalte benötigt. Zum Beispiel ein Script eines ColorPickers, den man für eine Design-Funkion benötigt.