2011-08-25 19 views
5

Bir grails uygulamasında belirli bir arka plan işleme kurulum türünü oluşturmaya çalışıyorum.Arka plan iş parçacıklarının arka plan iş parçacıklarını nohular olarak çağırma

  • A Sabit boyutlu parçacığı havuzu sadece
  • A tek oturumda her iş parçacığı tarafından tutulan işlerin toplu süresince için var Her iş ayrı işlem çalışır

İşi şu şekilde başlatmaya çalışıyorum:

int poolSize = 10 
ThreadFactory factory = new MyThreadFactory (Executors.defaultThreadFactory()) 
ExecutorService pool = Executors.newFixedThreadPool (poolSize, factory) 

(1..100).each { i -> 
    pool.submit { 
    try { 
     MyDomainClass.withTransaction { 
     doSomeWork(i) 
     } 
    } catch (Exception e) { 
     log.error "error in job ${i}", e 
    } 
    } 
} 

MyThreadFactory bir hazırda oturumuna sahip iplikler iplik süresince ekli yaratır.

class MyThreadFactory implements ThreadFactory { 

    ThreadFactory delegate 
    PersistenceContextInterceptor persistenceInterceptor 

    MyThreadFactory (ThreadFactory delegate) { 
    this.delegate = delegate 
    ApplicationContext applicationContext = ApplicationHolder.getApplication().getMainContext() 
    persistenceInterceptor = applicationContext.getBean("persistenceInterceptor"); 
    } 

    Thread newThread (Runnable work) { 
    return delegate.newThread { 
     persistenceInterceptor.init() 
     try { 
     work.run() 
     } finally { 
     persistenceInterceptor.flush() 
     persistenceInterceptor.destroy() 
     } 
    } 
    } 
} 

Bu işe yarıyor gibi görünüyor, ancak toplu işi ilk kez çalıştırdığımda aşağıdaki hatayı alacağım. I MyDomainClass.withNewSession {} ile persitanceInterceptor değiştirilmesi çalıştılar

groovy.lang.MissingMethodException: No signature of method: static MyDomainClass.save() is applicable for argument types: (java.util.LinkedHashMap) values: [[flush:false]] 
Possible solutions: save(), save(java.util.Map), save(java.lang.Boolean), wait(), any(), wait(long) 
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) 
at ... 

hiçbir etkisi ile, (Sonraki iş olaysız çalıştırın).

GORM yöntemleri etki alanı sınıflarıma enjekte edilmiyormuş gibi görünüyor.

Herkes yanlış yaptığımı görebilir ve neden toplu işi çalıştırmanın başarılı olmasını sağlar? iş bu halini alır Bütünlüğü için @fixitagain

:

doSomeWork = { id -> 
    MyDomainClass a = MyDomainClass.findById (id) 
    a.value = lotsOfWork() 
    a.save() 
} 

inanıyorum kırmızı ringa tasarrufu bir işlemde çalışan ambalajlama çalıştığım gibi, eksik ve ardından söyleyerek 'bir hata alıyorum DomainClass.withTransaction (Kapatma) 'tanımlı değil.

İlk işin çalıştırılamayacağı bir yarış durumu olabilir, ancak aşağıdaki tüm işler başarıyla çalıştırıldıktan sonra (? bir şey) başlatmayı tamamladı.

+0

Grails yaşam döngüsünün hangi noktasında işinize başlıyorsunuz? Etki alanları dinamik yöntemleri vb. Ile dekore edilmeden önce gerçekleşiyor gibi geliyor. –

+0

İşler denetleyici eyleminden tetikleniyor (şimdilik), böylece etki alanları dekore edildikten sonra. Tüm işleri ana iş parçacığından çağırırsam sorun olmayacağını unutmayın. – Akusete

+0

iyi, benim için GORM olası bir çözüm olarak kaydetmeyi (Harita) önerdiğinden beri "eklenmiştir". Kaydetmeyi kullandığınız çizgiyi koyabilir misin? BTW floş varsayılan olarak yanlıştır, yani Hazırda Bekletme oturumu sonunda temizlenecek demektir ... – fixitagain

cevap

1

Kendi iş parçanızı oluşturmaya çalışmak yerine, Grails için yönetici eklentisini kullanmanız tavsiye edilebilir. Oluşturduğunuz iş parçacığına gerekli hazırda bekleme oturumunu enjekte eder, ayrıca kullandığı yürütücüye, iş parçacığı sayısına göre yapılandırılabilir. Kuvartz işlerinde ve diğer senaryolarda üretimde kullanır ve gayet iyi çalışır.

Grails Executor Plugin Kullanmak için rezervasyonunuz varsa, kendi iş parçacığı stratejinizi yazmadan önce koduna bakabilirsiniz.

+0

İcracı eklentisine bir göz attım, ayrıca yeni iş parçacıklarında oturum oluşturmak için persistenceInterceptor kullanır. Şu anda muhtemelen bir eklenti kullanmadan önce nasıl grails/hibernate çalışır anladığımdan emin olmakla ilgileniyorum. Ama bahsettiğin için teşekkürler. – Akusete

+0

Yürütücü eklentisine ikinci bir bakıştan sonra, her zaman iş başına yeni bir oturum oluşturur. Genel olarak mantıklı olanı, ancak peşinde olduğum özel görev için değil. Yine de aynı mekanizmayı eklenti olarak oturum oluşturmak için kullanmaya çalışıyorum. – Akusete

+0

Neden Quartz eklentisini kullanmıyorsunuz? http://grails.org/plugin/quartz – felipenasc

0

Koddan veya adlandırma kuralından yararlanamıyorum, ancak etki alanı sınıfının bir örneğine kaydetmeyi çağırdığınızdan emin misiniz?

+0

Hata mesajı ile bir 'quirk' olduğunu farz ettim, meydan okuyan bir domain sınıf örneğinde save() çağırıyorum. Ayrıca, sorun buysa, ikinci kez çalıştırdığımda işin neden başarılı bir şekilde bitirileceğini açıklamayacağını anladım. A.save() işlevini çağırmadan önce – Akusete

+0

, a = a.merge() yardımında bulunur mu? – bluesman

0

Eksik yöntem istisnası, örnekte değil, Sınıfta kaydetmeyi çağırdığınızı gösterir.

düzenleme: GORM, önerilen çözüm yöntemi adlarında görebileceğiniz gibi, zaten ek yöntemler uygulamıştır.

İlgili konular