Linux’ta zamanlanmış görevlerde (cronjob) iş çakışmasını önlemek

Bir crontab girdisi belirli zaman diliminde çalışması için ayarlanmışsa (örneğin dakikada bir) ve bir sebepten yapılan işlemin belirtilen zaman diliminden fazla sürme ihtimali var ise, aynı komut bir öncekinin bitmesini beklemeden, zamanı geldiğinde tekrar çalışmak isteyeceğinden çakışma gerçekleşebilir.

Örneğin dakikada bir belirtilen kaynaktaki dosyaları işleyip veritabanına atan ve sonrasında kaynak dizini boşaltan bir uygulamamız için zamanlanmış görevimiz var. Diyelim ki gün için de öyle bir dakikaya geldik ki, o an tahmin edemediğimiz, öncesinde kestiremediğimiz şekilde, kaynağımıza fazladan dosyalar geldi. Yani o dakikada çalışan zamanlanmış görevin dosyaları işleyip veritabanına yollama işlemi 1 dakikadan fazla sürecek. Henüz program işlemini bitirmemişken 1. dakikanın sonunda aynı zamanlanmış görev, zamanı geldiği için tekrar çalışacak. Bu da veritabanında aynı verilerin tekrar etmesine sebep olacak.

Bu durumdan sakınmak için flock komutundan yararlanabiliriz.

flock'un basitçe kullanımı şu şekilde
flock -w 5 /herhangi/bir/yol komut
-w 5: eğer komut kullanımdaysa, belirtilen saniye kadar bekle. belirtilen sürede komut boşa çıkar ise, komutunu çalıştır.
/herhangi/bir/yol: Var olan herhangi bir dizinin altına belirleyeceğiniz yol. flock belirttiğiniz yola boş dosya oluşturacak.
komut: Çalıştırmak istediğiniz komut. mv, cp, wget, rm vs gibi.

flock kullanımını bir örnek ile göstereyim.

Görevimiz /dizin/kaynak/ yolu altındaki tüm dosyaları /dizin/hedef/ yoluna kopyalamak olsun.

Bunun için komut satırına şu şekilde bir girdi giriyoruz.

flock -w 0 /space/deneme cp /dizin/kaynak/* /dizin/hedef/

/dizin/kaynak/ yolunun altına büyük dosyalar atarak, kopyalama işlemi gerçekleştiren komutu çalıştırın.
Kopyalama işlemi devam ederken, aynı komutu terminal'de başka bir sekmede girmeyi deneyerek neler olduğunu görebilirsiniz.

Kaynak: http://www.elevatedcode.com/2013/05/07/flock-for-cron-jobs.html

1 Mart 2014

Posted In: Gezegen, linux

Çeviri sözlüğü yayında

Özgür yazılım çevirileri arasında arama gerçekleştirmenizi sağlayan Çeviri Sözlüğü yayında.

Proje fikri nereden çıktı?

Sitenin hakkında kısmında da değindiğim gibi, Yakın Doğu Üniversitesi İnovasyon ve Bilişim Teknolojileri'nde stajımı gerçekleştirirken özgür yazılım çevirilerine katkı sağlamıştık. Çeviriler yaparken en çok ihtiyaç duyduğum şey, birden fazla yaygın anlamı olan kelimenin daha önce hangi Türkçe karşılığı kullanıldığı oluyordu. Bence bu konu, çevirinin bütünlüğü açısından da önemli. Aynı projede hatta aynı programda kelimelerin ortak bir karşılığı kullanılması, kullanıcıların da isteyeceği bir şeydir diye tahmin ediyorum.

Burada öğrendiğim yöntem ile, çevireceğim kelimenin daha önceki çevirisini görmek için ilgili projenin tüm çeviri dosyalarını bir dizine indirip, komut satırından "grep" komutu ile bulmak istediğim kelimenin çevirilerini ekrana getirebiliyorum.

Zaman içerisinde bu işlemi web uygulaması ve veritabanı ile yapma fikri kafamda oluştu ve sitenin şuan ki hali meydana geldi.

Teknik olarak neler var?

Tüm çeviri dosyaları bir dizin altında bulunuyor. Ayıklama (parse) işlevi gören Java kodu, po uzantılı çeviri dosyalarını işleyerek İngilizcesini, Türkçe çevirisini ve dosya isimini veritabanına atıyor.

Linux Tomcat üzerinde çalışan Jsp de sorgu çekmenizi sağlayıp, sonuçları ekrana getiriyor.

Neden Java?

İşin kodlama kısmında Java teknolojilerini tercih ettim. .po dosyalarını ayıklama işlemi Python'da polib kitaplığı ile hali hazırda gayet pratik bir şekilde yapılabiliyor. Lakin Java'yı seçerek iş yerinde kullandığım ve öğrendiğim teknolojiler yardımı ile hali hazırdaki bilgi birikimi mi kullanabilecek, aynı zamanda bu proje ile yeni öğrendiğim şeyler iş yerinde bana faydası dokunabilecekti. Aynı şekilde veritabanında da Postgresql tercih etmemin sebebi hem özgür olması hem de iş yerinde kullandığımız bir sistem olmasıdır.

Yazdığım kodda doğrudan polib'den  yararlanmasamda, polib'in kaynak kodunu inceleyerek, ayıklama işi yapan Java kodu için fazlası ile ilham aldım.

Lictionary.in

Projeyi heyecanla ilerletirken bir yandan daha önce böyle bir çalışma olmuş ya da mevzu bahsi geçmiş mi diye araştırırken, lictionary.in sayfası ile karşılaştım. 2011 yılında gerçekleştirilen bu proje ile daha önce nasıl karşılaşmadım bilmiyorum.

Çevirileri tablolama açısından benim yapmak istediğim site ile tamamen aynı fikir üzerine kurulu. Daha önce yapılmış olanı yapmak bir süre hevesimi kırsa da, projenin eğitici yönünden dolayı yaptığım işi yarıda bırakmak istemedim.

Ne öğrendim?

.po dosyalarını ayıklama işlemlerini gerçekleştirirken temel Java bilgilerimi ilerlettim.
Postgresql bilgilerimi ilerlettim.
Jsp ile tanıştım.
Jsp'den gelen talepleri işlemek ve tekrar Jsp'ye göndermek için Servlet kullandım.

Bu proje bahanesi ile DigitalOcean'dan çok cüzi miktara Linux sunucu sahibi oldum. İnsanın elinin altında bandı geniş, alanı geniş bir VPS'i olması çok güzel :) Sitenin yayında olmasını sağlayan işlerin çok büyük çoğunluğunu kendim gerçekleştirdim. Daha önce LKD'nin eğitimine katıldığım ve LFS ile uğraştığım için işin en kolay kısmı Linux sistem yönetimi alanında oldu :)

DigitalOcean'dan kiraladığım sunucuya svn kurdum ve projeyi orada sakladım. svn co, svn up komutlarından öteye giderek svn yönetimi ile ilgili işleri öğrendim.

Ha unutmadan birde, sunucu sahibi olmadan önce projemi dışarısı ile paylaşmak için dizüstünde kurulu olan Ubuntu sistemi mi kullanıyordum. Bilgisayarımı barındırma olarak kullanabilmek için port yönlendirme, iptables vb konularda bilgi sahibi oldum. Bilgisayarımı barındırma olarak kullanmak gençlik hayalimdi :)

Sayfalama (pagination) işlemleri sırasında MVC ile tanıştım. Sürekli duyduğum birşeydi. Uygulamalı olarak tanımış oldum.

Temel HTML, CSS kodlarını öğrendim.

Proje ile uğraşırken karşılaştığım sorunlar ve çözümleri

Birileri sayfama giripte, "bunu nasıl yapmış acaba" diyebileceği ve aynı zamanda benim üzerinde bir süre takıldığım konularda yararlandığım kaynakları paylaşmak istiyorum.

tablonun css'i için hazır kodlar kullandım. Ufak tefek değişiklikler dışında olduğu gibi kaynaktan yararlandım

http://johnsardine.com/freebies/dl-html-css/simple-little-tab/

Sonuçları sayfalamak için aşağıdaki kaynağı takip ettim. Üzerine eklemeler yaptım. İlerleyen sürümlerde tablolamada jQuery'ye geçecek olsam da, MVC öğrenmeme vesile olması sebebiyle taglib (JSTL) kullandığıma pişman değilim.

http://theopentutorials.com/examples/java-ee/jsp/pagination-in-servlet-and-jsp/ 

Tomcat'te Türkçe karakter sorunu yaşadım. Konu Jsp ile alakalı zannederek Google'da bu konudaki bir çok sayfayı tekrar tekrar ziyaret ettim. Lakin bakış açımı değiştirince çözüm Tomcat'te olduğunu farkettim. Bunun ile ilgili

http://struts.apache.org/release/2.0.x/docs/how-to-support-utf-8-uriencoding-with-tomcat.html

Html etiketlerini düz metin olarak göstermek için

http://stackoverflow.com/questions/6817262/how-to-display-html-tags-as-plain-text


Sistem tarafında iş arkadaşım Gökhan Atmaca'dan, kodlama ve arayüz konusunda diğer çalışma arkadaşlarımdan epeyce fikir aldım. Onlara da teşekkürler.

Biterken

Veritabanı üzerinde çalışmak isteyenler için, yedeğini (dump) paylaşabilirim.

Henüz 5 aylık Java serüvenim var. Bulduğunuz hata veya absürtlükleri değerlendirirken bunu göz önünde bulundurarak değerlendirirseniz sevinirim. 

Böyle ufak bir proje için bu kadar dil dökmüş olmamı garipseyebilirsiniz, lakin yazmayı seviyorum :)

Gelecek sürümlerde görüşmek üzere.


29 Ocak 2014

Posted In: çeviri sözlüğü, Gezegen, java, linux, programlama

Java split() metodunda kırpmanın önüne geçme

Java'da bir dizgeye split() metodunu uyguladığımız zaman, dizgenin son kısımlarında boş (yani "") dönmesi gereken alanlar kırpılıyor ("trim" uygulanıyor).

Örneğin aşağıdaki gibi bir dizgemiz olsun.
String degerler = "0|0|0|1|||0|1|0|||";
degerler dizgesini boruya (pipe, "|") göre split() ettiğimde karakter dizisi içerisinde geriye "0", "1" yada "" değerleri dönecek.
String[] karakterDizisi = degerler.split("\\|"); 
Yukarıdaki kodu uyguladıktan sonra split() metodu en sondaki "0" rakamından sonraki  "|||" kısmını kırpıyor ve boş değerleri listeye dahil etmiyor.  Bu durumda karakterDizisi'nin uzunluğu 9 dönüyor.

Bu durum String.split(String regex) bağlantısında açıkça belirtilmiş.

Kırpılan alanları da karakter dizisine eklemek istiyorsanız, sınırlama değeri girmelisiniz. Sınırlama değeri  split() metodunun dizgeye kaç defa uygulanacağını belirtir.  split() metodunun kaç defa uygulanacağına dair bir sınır girmek istemiyorsanız eksili bir sayı girmeniz yeterli.

Sınırlama değeri ile kullanmak için sözdizimi şu şekilde: String.split(String regex, int limit)

Örnek olarak;
String[] karakterDizisi = degerler.split("\\|", -1); 

Artık karakterDizisi uzunluğunda bir sınır yok ve boş alanlar da listeye dahil. Yukarıdaki kodu uyguladıktan sonra listenin uzunluk değeri 12 dönüyor.

Kaynak: http://stackoverflow.com/questions/14414582/java-split-string-to-array

18 Ocak 2014

Posted In: Gezegen, java, programlama, split metodu

Gnome 3’te kullanıcı resmi bilgileri

Gnome 3 kullanan dağıtımlarda sistemde kullanıcı resmi bilgileri 2 dizinde işleniyor.

Birincisi /var/lib/AccountsService/users
İkincisi /var/lib/AccountsService/icons

/var/lib/AccountsService/users

Dizinin altında her kullanıcı için .desktop dosya yapısına benzer bir metin dosyası mevcut. /var/lib/AccountsService/users/[Kullanıcı Adı] şeklinde tutuluyor. Kurulum esnasındaki tercihlere göre Ubuntu'da ortalama varsayılan olarak şöyle geliyor.
[User]
XSession=ubuntu
XKeyboardLayouts=
Kurulumdan sonra bir kullanıcı resmi belirlersek dosyaya "Icon=" ile başlayan bir satır ekleniyor. Eğer sistemin sunduğu resimlerinden seçerseniz "Icon=" karşısına seçilen resmin yolunu yazar. Başka bir yoldan resim seçerseniz resmi /var/lib/AccountsService/icons dizini altına seçimi yapan kullanıcının ismi ile bir resim dosyası oluşturur (/var/lib/AccountsService/icons/[Kullanıcı Adı] gibi) ve "Icon=" karşısına bu oluşturduğu resmin yolunu yazar.

/var/lib/AccountsService/icons

Seçtiğiniz resim Kullanıcı Hesapları uygulamasındaki sunulanın dışında bir resim ise, uygulama seçilen resmi /var/lib/AccountsService/icons dizini altına, 96x96 piksel boyutuna getirip, seçimi yapan kullanıcı adını dosya ismi olarak kullanarak, png formatına çevirerek atar.

Herhangi bir resim seçtikten sonra users dizini altındaki dosyanın son hali
[User]
XSession=ubuntu
XKeyboardLayouts=
Icon=/var/lib/AccountsService/icons/volkan

Kaynak:
http://askubuntu.com/questions/61637/where-is-the-users-profile-picture-stored-in-gnome-3
http://comments.gmane.org/gmane.comp.gnome.gdm.general/2513

29 Mart 2013

Posted In: Gezegen, gnome 3, linux

WP Twitter Auto Publish Powered By : XYZScripts.com