domingo, 22 de junho de 2014

[HTML 5] Web Workers

Essa vai de uma das questões do simulado para o exame 70-480 da Microsoft (HTML 5, JavaScript e CSS3).

A API Web Worker permite executar scripts em background (em uma thread separada da thread principal), sem bloquear a execução da página. A API é implementada no objeto Worker.

Você deve, antes de mais nada, instanciar o objeto Worker usando a palavra chave "new", atribuindo a instância resultante a uma variável, conforme o exemplo:

var worker = new Worker("ArquivoComScriptParaExecutar.js");

O parâmetro do construtor é o arquivo JavaScript que contém o script que será executado em background. Tipicamente são tarefas de longa duração, que poderiam bloquear a execução da página principal por algum tempo. O código do script pode informar o término da execução pelo envio de uma mensagem para o seu chamador, através da função postMessage.

Posteriormente, é necessário associar um event handler ao evento onmessage do objeto Worker. Isto permite à thread principal ser notificada do final da execução do script em background. Para manipular o evento com uma função anônima faça o seguinte:

worker.onmessage = function(e) {window.alert(e.data);};

O parâmetro para a função anônima é um event object. Este objeto contém uma propriedade data, que é o dado enviado como parâmetro pela função postMessage. Esta propriedade pode ser tanto uma string quanto um JSON (JavaScript Object Notation).

O script em background inicial quando o evento onmessage é invocado pelo objeto Web Worker e com o seguinte código, força-se a execução da função anônima no script em background:

worker.postMessage("");

A função AddEventListener permite a você associar um event handler a um evento. O primeiro parâmetro da função deve especificar o nome de um evento, não o nome do script em background. O segundo parâmetro deve especificar uma função de callback ou uma função anônima.

A função close do objeto Worker termina a thread avulsa e é chamada no script em background.

Exemplo:

Script em background (Workers.js):

onmessage = function(e){
  setTimeout(function()
  { 
    postMessage("Terminou a execução em background!");
  }, 5000);
}

Página (chamaWorker.html):

<!DOCTYPE html>
<html>
<head>
  <title></title>
</head>
<body>
<script>
 var worker = new Worker("Worker.js");
 worker.onmessage = function(e)
 {
   window.alert(e.data); 
 };
 worker.postMessage("");
</script>
</body>
</html>

sexta-feira, 20 de dezembro de 2013

domingo, 20 de janeiro de 2013

[JPA] Conceitos Importantes

Fonte: http://tomee.apache.org/jpa-concepts.html

Se tem uma coisa que você precisa entender para usar com sucesso a JPA (Java Persistence API), é o conceito de Cache. Infelizmente o cache é uma estrutura interna, não exposta pela JPA via código.

O que você tem que ter em mente sobre o cache da JPA:
  • Um Cache é uma cópia de dados, uma cópia desconectada do banco de dados.
  • Flushing é o ato de levar as modificações feitas em cache para o banco de dados.
  • Um PersistenceContext é, essencialmente, um Cache.
  • Um EntityManager represetne um PersistenceContext (logo, um cache).
  • Um EntityManagerFactory cria um EntityManager (e todavia um PersistenceContext/Cache).

Comparando os contextos de persistência RESOURCE_LOCAL e JTA.

Com <persistence-unit transaction-type="RESOURCE_LOCAL"> você é que se responsabiliza por criar e rastrear o EntityManager (PersistenceContext/Cache).

  • Você precisa usar o EntityManagerFactory para obter um EntityManager.
  • A instância do EntityManager obtida é um PersistenceContext/Cache.
  • Um EntityManagerFactory pode ser injetado com a anotação @PersistenceUnit apenas (sem @Persistence Context).
  • Não é permitido usar @PersistenceContext para se referir a uma unit do tipo RESOURCE_LOCAL.
  • Você deve usar EntityTransaction API para iniciar/comitar todas as chamadas para seu ENtityManager.
  • Chamar ENtityManagerFactory.createEntityManager() duas vezes resulta em duas instâncias separadas de EntityManager e, é claro, dois PersistenceContext/Caches separados.
  • Não é uma boa idéia ter mais de uma instânciade um EntityManager em uso (não crie um segundo EntityManager antes de destruir o primeiro).

Com <persistence-unit transaction-type="JTA"> o container irá cuidar da criação e do rastreamento do EntityManager para você, e neste caso:


  • Você não pode usar o EntityManagerFactory para obter um EntityManager.
  • Você só pode ter o EntityManager que é fornecido pelo container.
  • Um EntityManager pode ser injetado pela anotação @PersistenceContext, somente (sem @PersistenceUnit).
  • Você não pode usar @PersistenceUnit para fazer referência a uma unit do tipo JTA.
  • O EntityManager fornecido pelo container é uma referência ao PersistenceContext/Cache associado a transação JTA.
  • Se não há transações JTA em progresso, o EntityManager não pode ser usado porque não há PersistenceContext/Cache.
  • Qualquer um com uma referência para a mesma unit na mesma transação irá automaticamente ter uma referência para o mesmo PersistenceContext/Cache.
  • O PersistenceContext/Cache é flushed e limpo a cada commit JTA.

É isso aí! Mais informações e exemplos veja em http://tomee.apache.org/jpa-concepts.html