SyncedOutputCache ile Aynı Anda Invalide Olan Output Cache Implementasyonları

By Burak Tungut - 2.3.2016 - Kategori Asp.Net MVC

Selam millet!

Küçük bir ev taşıma, yerleşme arasından sonra tekrar beraberiz. Aslında Elasticsearch ve SOLID konularında ayrı ayrı yazı dizileri başlatmıştım fakat okuyacağınız bu makalede bunlara hiç değinmedim. Geçtiğimiz haftalarda iş yerinde geliştirdiğimiz bir üründe doğan bir ihtiyacımıza karşı bir implementasyon yapmak durumunda kaldık. Size bu tecrübemi aktarmak istiyorum.

OutputCache Şart Oldu

Öyle bir ürün düşünelimki kullanıcı adı ve şifremiz ile authenticate oluyor ve uygulamada gezinmeye başlıyoruz. Fakat öyle sayfalarımız varki içerisindeki sayıların, data'ların uyuşması, tutarlı olması gerekli. Diğer bir yandan ise performans için disk'ler üzerindeki IO'yu düşürmek istiyoruz.

Böyle bir durumda akla Output Cache kullanmak gelebilir. Fakat Asp.Net MVC içerisinde halihazırda var olan OutputCacheAttribute bu ihtiyacımızı tam olarak karşılamayacaktır. Çünkü var olan output cache implementasyonu söz konusu action execute edildikten sonra çalışır. Bu da sayfaların (ya da partial'ların) cache'e alınmış hallerinin aynı anda invalide olmayacağı ihtimali anlamına gelir.

Anlaşılabilir olması için şöyle bir örnek ile ilerleyelim. A sayfamızda sipariş verilmiş ürünlerin sayısı gösterilirken, detayları içeren sayfası sipariş verilmiş olan ürünlerin detayını göstersin. Eğer A ve B sayfaları aynı source'u kullanmıyorsa bu sayfaların output cache'e alınması tutarlı sayıların gösterilmesi yönünde bizi zor duruma sokabilir. Birinin cache'i 3 dakika diğerinin 15 dakika sonra invalide olacağını düşünürsek yeni gelmiş olan kayıtlara ait data ya da sayılar birinde gözükürken diğerinde gözükmeyecektir.

İşte bunun gibi durumları ortadan kaldırabilmek için tüm cache'leri sync hale getirmemiz gerekebilir. Biz bunu yaparken var olan OutputCacheAttribute'ünü inherited etmiş yeni bir sınıf kullanacağız. Amacımız ise x zamanında gelen ve output cache'e alınmak istenen bir request'in x+10 ya da x+60 gibi bir sürede invalida olması değil, bir sonraki 10. ya da 60. (bu sayı bize kalmış, parametrikte olabilir) dakikada invalide olması.

Şöyle bir senaryo düşünebiliriz. A sayfasına 23.03'de girildi ve cache'e alındı. Bu cache'in invalide işlemi 23.10'da yapılmalı. Hal böyleyken 23.07 de dahi B sayfasına girilse burası için yaratılan cache'de 23.10'da invalide olacaktır.

Yani cache'lerimiz sonraki dakika bloğunu tamamlayacak şekilde expire olmalı.

Expire Zamanının Hesaplanması

Şimdi yukarıdaki anlatılan business'a göre expire zamanının hesaplanmasını gerçekleştirelim. Öyle bir method yazmalıyız ki parametre olarak expire edilecek dakikayı almalı (10,15,30 gibi) ve geriye söz konusu cache'in tam olarak hangi zamanda invalide edileceğini bildiren bir değer döndürmeli. Bu değerin DateTime olması daha anlaşılabilir olacağı için aşağıdaki gibi bir method yazabiliriz.

private DateTime GetExpireDateTime(int expirationMinute)
{
    var retVal = DateTime.Now;

    retVal = retVal
        .AddSeconds(retVal.Second * -1)
        .AddMilliseconds(retVal.Millisecond * -1);

    if (expirationMinute == 60)
    {
        retVal = retVal
            .AddHours(1)
            .AddMinutes(retVal.Minute * -1);
    }
    else
    {
        retVal = retVal
            .AddMinutes(expirationMinute - retVal.Minute);
    }

    return retVal;
}

Bu methoda gelecek olan expirationMinute aslında bir expire block niteliği taşıdığı için 60 gelme durumu da söz konusu olacaktır. Örneğin 15. dakikanın katlarında invalide olması istenen sayfalarımız varsa herhangi bir saatin 45. dakikasından sonra gelecek olan bir request sonraki saatin ilk saniyelerinde invalide olmalıdır. Bu nedenle 60 olması durumunda bir sonraki saatin dakika, saniye ve saliselerini siliyoruz.

Devamı

Eskişehir Osmangazi Üniversitesi The Code Day Etkinliğimiz

By Burak TUNGUT - 4.5.2013 - Kategori Genel

Yazılım Dilleri olarak yıl içerisinde yaptığımız bir çok The Code Day etkinliğini bu haftasonu da Eskişehir Osmangazi Üniversiteinde gerçekleştirdik!

Veysel Uğur KIZMAZ ile beraber gerçekleştirdiğimiz etkinlikte genel olarak Windows Azure, Asp.Net MVC ve uygulamalarından bahsettik.

Eskişehir Osmangazi Üniversitesi Burak TUNGUT

İlk oturumlarda biz aday mühendisler için sektör hakkında bolca bilgi veren Veysel Uğur KIZMAZ ile ilerleyen saatlerde çekilişler ile bir çok öğrenci arkadaşa kitaplarını verdik.

Devamı

Asp.Net MVC Output Cache Kullanımı ve İstisna Senaryoları

By Burak TUNGUT - 24.3.2013 - 2 Yorum - Kategori Asp.Net MVC

Öncelikle herkese merhabalar smiley Bu makalemde Asp.Net MVC uygulamalarında sıklıkla kullanılan bir önbellekleme yöntemi olan OutputCache filter’ının kullanımını inceliyor olacağız. Web projelerinin en büyük sıkıntıları hiç şüphesiz performans kayıplarıdır. Bunu büyük ölçüde absorbe  etmek içinde doğru yerlerde olma şartıyla caching işlemleri yapılır.Asp.Net MVC Output Cache

Örneğin günde yüzbinlerce kişinin girdiği, hepsiburada.com gibi bir siteyi ele alalım. Kategoriler arasında dolaşıyor, ürünleri inceliyor ve sipariş veriyorsunuz. Ancak hangi sayfada olursanız olun üst tarafta kategorileri hep görüyorsunuz. Yüzbinlerce kişinin bu sitede en az 3 sayfayı gezdiğini bile düşünürseniz kategoriler kısmının her seferinde veri tabanından çekiliyor olması büyük performans kayıpları yaşatacaktır.Sonuçta bu kısım an ve an değişiklik gösterebilen bir bölüm değil. Böyle bir siteye kategori eklenmesi belki birkaç ayda bir gerçekleşir.

Sonuç itibariyle böyle bir durumda yani kısa süreçler içerisinde değişime uğramayan veya anlık bilgi üretmeyen kısımların önbelleklenmesi (caching) büyük ölçüdeki performans kayıplarını bir hayli absorbe edecektir.

Bunun yanı sıra az önce “anlık bilgi üretmeyen…” kısmıyla da belirttiğim gibi durumlarda ise caching yapılması mümkün olup, istenilen sonuçların doğru üretilebilmesi çeşitli konfigürasyonlar ile sağlanabilmektedir.

Caching Çeşitleri

Caching işlemlerini Data Caching ve Output Caching olmak üzere ikiye ayırabiliriz.
Data Cache işlemleri .Net üzerinde, desteklediği tüm veri ve referans tiplerini ön bellekleyebileceğimiz ve her bir istekte ise önbellekten aynı veriyi alabileceğimiz bir model sunar. Böyle bir önbellekleme için yukarıda verdiğimiz örneği ele alırsak, veri tabanına bir kere bağlanılır ve çekilen kategori nesneleri data cache ile ön belleklenebilir.

Makalede inceleyeceğimiz Output Cache modeli ise çıktıların yani render edilmiş View bilgilerinin ön belleklenmesini ve timeout olana kadar gelen her bir istekte ise bir önceki ön belleklenmiş bilgilerin sunulmasını sağlar. Aynı örnek üzerinden ilerleyecek olursak output cache ile kategoriler kısmının ön belleklenmesi için kategoriler kısmını içeren bir PartialView’ın tamamının cache edilmesi gerekir.

Anlık değişim içerisinde olmayan bir çok verinin aynı sayfa üzerinde olacağı durumlarda, toplu bir cache mekanizmasına sahip olduğu için Output Cache kullanımı daha tutarlı bir çözüm olacaktır.

Cache yöntemlerinden ve istisna durumlarından da bahsettiğimize göre artık yapacağımız küçük uygulamalara geçebiliriz laugh

OutputCache kullanım kolaylığı sağlanması için Action Filter sınıfından kalıtılmıştır. Bu sayede Controller veya altında oluşturulabilecek Action’lar için Attribute olarak kullanılabilirler.

OutputCache Attribute'ün Kullanımı

Uygulamalarımızı yapabilmek için bir adet Asp.Net MVC 3 ya da 4 projesi açalım.
HomeController altında GetTime adında bir adet action yaratalım ve aşağıdaki gibi kodlayalım;

namespace MVCAuth.Controllers
{
    public class HomeController : Controller
    {
        [OutputCache(Duration=10)]
        public ActionResult GetTime()
        {
            ViewBag.Date = DateTime.Now.ToString();
            return View();
        }
    }
}

Devamı

Asp.Net MVC - IExceptionFilter Implementasyonu İle Hata Yakalama

By Burak TUNGUT - 9.3.2013 - 1 Yorum - Kategori Asp.Net MVC

Herkese merhabalar. Yaklaşık 2 haftadır yazmayı hatta yazacağımda uygulamak istediğim senaryoyu bile kafamda tasarladığım makalem ile karşı karşıyayız cool Geçtiğimiz 3 ay boyunca MVC patterni üzerine yoğunlaşmama rağmen bu alanda makale paylaşımlarımın eksik olduğumu gözlemledim. Aslında amacım Asp.Net MVC için düzenli ilerleyecek bir yazı dizisi hazırlamaktı fakat bu alandaki ilk makalemin başlığı, “Asp.Net MVC - Arama Motoru Dostu linkler için Custom Link Senaryosu” şeklinde olunca giriş seviyesi konuları biraz atlamış oldum cheeky

C# ile Web Forms ya da MVC olsun herhangi biri ile web projesi geliştiren herkes eminim ki aşağıdaki manzara ile karşılaşmıştır;

Asp.Net MVC Exception

“Kahretsin!! Evettt” diyenleri duyar gibiyim J Sarı arka plan üzerine kurulmuş şu sayfayı gördüğümüzde hiç şüphesiz işlerin ters gittiği kesindir. Birde son müşteri için hizmete açılmış bir projede böyle bir şeyin olduğunu hayal edelim. Ya da vazgeçtim. Hayal etmesek daha iyi gibi. Pekte güzel bir hayal olmadı blush Tabi ki bu hayali daha doğrusu kabusun yaşanmaması için bir şeylerin yapılması gerekir.

Senaryomuzu Tanıyalım

Aslında yapılması gereken olgu için ipucunu daha önce verdim (Bknz.: Makale Başlığı). Asp.Net MVC platformunun bizler için sunduğu çeşitli hata ayıklama mekanizmaları mevcut.  Aklıma gelenler için bunları şöyle sıralıyabiliriz;

1.       Application_Error metodunun yazılması

2.       IExceptionFilter interface’ini implemente eden bir filter yazılması

3.       IIS Custom Error kullanılması

Aklıma gelen bu üç yöntemden OOP tekniklerine daha yatkın olduğu için ikincisini tercih ettim.

Bugünkü senaryomuz olabildiğince basit. Elimizde bir web projesi var. Ana sayfasında ise sadece “Hata Fırlat” ismine sahip ve tıklandığında ise Exception fırlatacak bir link olsun. Tabi ki bu linke tıklandığında daha önce herhangi bir hata yakalama işlemi yapılmadığı için, yukarıda lanetler okuduğumuz sarı arka planları bir sayfa ile karşılaşıyor oluruz.

Projeyi uygulamaya geçirme işlemine, controller ve action’lardan başlayalım. Bunun için içi boş bir MVC projesi oluşturalım ve HomeController altına Index, Throw ve Error adlı üç adet ActionResult ekleyelim.  Index adlı ve Error adlı actionlar için birer view oluşturalım. Throw adlı action için herhangi bir view oluşturmayalım. Hata fırlatacak action’ın view ile ne işi olur laugh

HomeController Sınıfının Kodları

public class HomeController : Controller
    {
        public ActionResult Index()
        {
            return View();
        }

        public ActionResult Throw()
        {
            throw new Exception("Ben Fırlatırım, Sen Yakalarsın!");
        }

        public ActionResult Error()
        {
            return View();
        }
    }

Yukarıda bahsettiğimiz gibi Throw action'ının bir view'e bağlanması gereksizdir. Dikkat ederseniz herhangi bir return işlemide bu metot içerisinde uygulanmamıştır. Hatta Visual Studio varsa return sözcüğünün bizim için gereksiz olduğunuda söyleyecektir.

Devamı

Asp.Net MVC - Arama Motoru Dostu linkler için Custom Link Senaryosu

By Burak TUNGUT - 26.1.2013 - 3 Yorum - Kategori Asp.Net MVC

Öncelikle herkese merhabalar :) Yaklaşık 2 aydır aşırı tempolu geçen bir dönem içerisindeydim. Neyse ki dersler, projeler derken sonun da hepsini atlattım. Tabi tatil dönemini yarılamış olmamda beni bir hayli üzüyor. Bazen sormuyor değilim kendime zaman ne çabuk geçti diye J

Neyse artık yavaş yavaş  bugünkü konumuza gelelim.

Uzun zamandan beri Asp.Net MVC hakkında bir yazı dizine başlamak istiyordum. Bu başlangıcı aslında geçtiğimiz haftalarda Asp.Net MVC Giriş adlı webiner ile yaptım. Bu günkü konumuz ise View tarafında Link işlemlerinin nasıl yapılacağı olacak.  Bunun yanında Helper sınıflar için extension metotlar yazarak kendimize özel (Custom) Link’ler yaratılmasını sağlayacağız.
Tüm bunları yaparken örneğin teoride kalmaması için biraz Routing ayarlaması ile de uğraşacağız tabi ki :)

Senaryomuzu Tanıyalım

Bugün yapacağımız örnekleri bir Haber sayfası senaryosu üzerinden yapacağız. Bunun için öncelikle her ne kadar var olmasa da News adında bir veri tabanı tablomuzun olduğunu düşünelim ve bu tabloyu bir entity class niteliğinde modelleyelim.

Model klasörümüz altında bir adet sınıf oluşturalım ve modelleme işlemimizi aşağıdaki kodlar yardımıyla gerçekleştirelim;

public class News
    {
        public int Id { get; set; }
        public string Title { get; set; }
        public string Content { get; set; }
    }

Deneme amaçlı olarak kullanacağımız ve elimiz ile birkaç haber kaydı ekleyeceğimiz için sade bir model oluşturamaya özen gösterdim.

Haber Depomuza Kayıtlarımızı Ekleyelim

Az önce bahsettiğim gibi az da olsa birkaç kayıt uygulamamızı çalışır hale getirmek için yeterli olacaktır. Bunun için News sınıfı içerisinde Repository adında bir property tanımlayalım. Bu property bizlere ekleyeceğimiz 10 adet haber kaydını sunsun. Bu durumda tipimiz bir collection olacaktır. Fakat her ulaştığımızda tekrar tekrar bu işlemi yapmaması için küçük bir encapsulation uygulamakta fayda var.

Dediklerimizi şöyle toparlayalım o zaman. Biri public diğeri private olan iki adet static property tanımlayalım ve haber kayıtlarını ilk çalışma anında yükleyecek bootstrap tadında bir metot yazalım.

O zaman News sınıfımızın içerisine aşağıdaki kod parçalarını da ekleyelim;

private static IList<News> _Repository = null;
        public static IList<News> Repository
        {
            get
            {
                if (_Repository == null)
                    _Repository = GetNews();
                return _Repository;
            }
        }

        private static IList<News> GetNews()
        {
            var result = new List<News>();
            for (int i = 1; i <= 10; i++)
            {
                result.Add(new News
                {
                    Id=i,
                    Title=string.Format("{0}. Haberin Başlığı",i),
                    Content = string.Format("{0}. Haberin İçerik Detayı")
                });
            }
            return result;
        }

Devamı
1
Facebook
Son Yorumlar