Não importa

Devaneios de um DesDevOps

Cron Vs Anacron: Como configurar o Anacron no Linux

O Anacron é o cron para desktops e notebooks. O Anacron não espera que o sistema continue rodando 24 x 7, como um servidor. Quando você precisar que um job fique automaticamente rodando em backgroud em uma máquina que não roda como um servidor, você deve usar o Anacron.

Por exemplo, se você tem um script de backup agendado para todos os dias às 23hrs como um job comum do cron, e se seu notebook não estiver ligado às 23hrs, seu script de backup não será executado.

No entanto, se você tiver o mesmo job agendado no anacron, você pode ter certeza que ele será executado assim que o notebook for ligado.

Formato do Anacrontab

Assim como o cron tem o arquivo /etc/crontab, o anacron tem o /etc/anacrontab

O arquivo /etc/anacrontab tem seus jobs anacron mencionados no seguinte formato:

período     atraso     Identificador do Job     comando

O primeiro campo é o período de recorrência: Esse será um valor numérico que especificará o número de dias até o job ser executado.

  • 1 – diariamente (daily)
  • 7 – semanalmente (weekly)
  • 30 – mensalmente (monthly)
  • N – Esse pode ser qualquer valor numérico. N indica o número de dias

Nota: Você também pode usar ‘@monthly’ para um job que precisa ser executado mensalmente.

O segundo campo é o atraso: Esse indica o tempo de atraso em minutos. Isto é, a quantidade de minutos que o anacron deve esperar, após a máquina ser ligada, para executar o job.

O terceiro campo é o identificador do job: É o nome para o arquivo que guardará o timestamp do job. Ele deve ser único para cada job. Ele estará disponível em um arquivo dentro do diretório /var/spool/anacron. Este arquivo conterá uma única linha indicando a última vez que o job foi executado.

ls -l /var/spool/anacron/
test.daily
cron.daily
cron.monthly
cron.weekly

O quarto campo é o comando: O comando ou script shell que precisa ser executado.

Assim como em scripts shell, comentários dentro do arquivo anacrontrab começam com #

Exemplo Anacron

O exemplo a seguir execute o script /home/fabioluciano/backup.sh a cada 7 dias.

No dia em que o script o job com o backup.sh supostamente deveria ser executado, se o sistema estiver desligado por qualquer razão, o anacron vai executar o job, 15 minutos depois que a máquina for ligada(não tendo que esperar mais sete dias)

cat /etc/anacrontab
7       15      test.daily      /bin/sh /home/fabioluciano/backup.sh

START_HOURS_RANGE e RANDOM_DELAY

O exemplo acima indica que o script backup.sh deve ser executado todos os dias, com um atraso de 15 minutos, isto é, quando o notebook for ligado, execute apenas após 15 minutos passados.

O que acontece quando o notebook ou desktop não estiver desligado? Quando esses jobs serão executados? Isso é especificado pela variável de ambiente START_HOURS_RANGE no arquivo /etc/anacrontab.

Por padrão é setado no arquivo para 3-22. Isso indica o intervalo de tempo de 03:00hrs até 22:00hrs.

grep START /etc/anacrontab
START_HOURS_RANGE=3-22

Acima do valor de atraso especificado no segundo campo no arquivo /etc/anacrontab, o anacron também adiciona randomicamente x número de minutos ao atraso. O x é definido pela variável RANDOM_DELAY no arquivo /etc/anacrontab.

Por padrão é setado no arquivo para 45. Isso significa que o anacron vai adicionar x minutos(randomicamente escolhidos entre 0 e 45), e adicionar ao atraso definido pelo usuário.

grep RANDOM /etc/anacrontab
RANDOM_DELAY=45

Cron Vs Anacron

Cron Anacron
Menor granularidade é em minutos (isto é, jobs podem ser agendados para serem executados à cada minuto) Menor granularidade é somente em dias
Cron Job pode ser agendando por usuários normais (se não for restrito pelo super usuário) de fazê-lo usável por usuários normais)
Cron Job pode ser agendando por usuários normais (se não for restrito pelo super usuário) Anacron pode ser usado somente pelo super usuário (mas existem meios de fazê-lo usável por usuários normais)
Cron espera por sistemas rodando 24 x 7. Se um job foi agendando, e o sistema estiver desligado durante o horário setado, o job não será executado. Anacron não espera que o sistema esteja rodando 24 x 7. Se um job foi agendando, e o sistema estiver desligado durante o horário setado, ele executará os jobs assim que o sistema estiver ligado
Ideal para servidores Ideal para desktops e notebooks
Use o cron quando um job precisa ser executado em uma hora e minuto em particular Use o anacron quando um job precisa ser executado independente da hora e minuto

Minhas cinco razões para não usar nomes de variáveis curtos

Outro dia desses esbarrei numa linha como essa revisando código:

sysMgrH = vFgrMan

ou

parse1(l, e, arr);
parse2(l2, e2, arr);

Por favor, não faça mais isso! Escolha nomes de variáveis longos e claros, nada mais! Por que?

  • Atualmente é permitido ter nomes de variáveis maiores que um, e ainda maiores que dez caracteres, se você precisar.
  • Seu trabalho não é economizar tempo digitando menos ou trinta segundos, trata-se de produzir algo de alta qualidade. E algo que dê pra mater. E sustentável.
  • Na verdade, escrever o código é apena 1% do seu tempo, comparando com o resto, como por exemplo, pensar o que se deve escrever. Você pode também perder alguns segundos na parte da escrita.
  • Se você se preocupa em ter de escrever o mesmo nome de variável de 12 caracteres várias vezes: faça amizade com Ctrl %2B Space.
  • Mas minha razão atual, minha principal razão é a seguinte: você não escreve essa parte do código para você e para agora. Isso continuará existindo pelos próximos cinco ou dez anos, e se você tiver sorte, dezenas de desenvolvedores irão ver isso. E alguns deles, precisarão entendẽ-lo. Em dois meses, em um ano, em cinco. Mas para eles, não é uma questão de 30 segundos (que é o tempo que você economizou cinco anos atrás, lembra?), tenha em mente que, em média, mais de 50% dos custos de desenvolvimento de software são gastos após a versão inicial está concluída.

Então aqui vai o meu apelo: seja legal e escreva o código como se você escrever um romance. Escolha palavras agradáveis, escolha palavras longas, e formate tudo bem. Pense no seu colega desenvolvedor, no futuro, que vai agradecer por isso.

Post Original: http://www.hendrikbeck.com/2010/08/03/my-5-reasons-not-to-use-short-variable-names-anymore/

Padrões de projeto - Abstract Factory

Começando com a nossa jornada a compreensão dos padrões de projeto que usaremos no futuro de nossos projetos para torná-los mais fáceis de manter, começaremos com o design pattern Abstract Factory

Tipo de padrão

Criacional

Intenções

  • Prover uma interface para criar famílias de objetos relacionados ou dependentes, sem especificar suas classes concretas.
  • Criar uma hierarquia que encapsula: algumas possíveis “Plataformas”, e a construção de um grupo de “produtos”.
  • O operador new é considerado prejudicial a estrutura.

Aplicabilidade

Devemos usar o padrão Abstract Factory quando:

  • O sistema precisa de indenpendência de como os produtos se comportam quando são criados.
  • O sistema precisa ou precisará ser configurado para trabalhar com diversas famílias de produtos.
  • Uma família de produtos é desenhada para trabalhar apenas quando todos juntos.
  • Uma biblioteca de produtos é necessária, para as quais é relevante não somente a interface, mas a implementação também.

Diagrama

Diagrama da Estrutura de Classes

Exemplo

Nosso exemplo é composto por quatro classes principais, sendo elas:

  • Convert_Abstraction_AbstractFactory - A Fábrica em sí. Direciona o Fluxo de acordo com a especialização.
  • Convert_Abstraction_Factory - O Nosso Objeto Abstrato, responsável pelas definições comuns aos objetos produtos.
  • Abstract_Factory_Convert_PNG e Abstract_Factory_Convert_JPG - Nossos objetos Concretos.

Objeto abstrato

A classe abaixo representa o nosso objeto abstrato, que como você verá não será invocado nenhuma vez por nenhum script, apenas estanciado pelos objetos concretos. É importante notar também a presença das constantes que serão usadas pelos objetos concretos e a interface, contendo o método que deve ser comum a todos os objetos concretos.

<?php

interface iFactory {
    public function image_convert($img);
}

abstract class Convert_Abstraction_Factory  implements iFactory {

    const IMG_PATH  = './img';
    const TMP_PATH  = './tmp';
    const CONV_PATH = './conv';

    protected function __construct() {}

    protected function to_pnm($img) {
        $time = time();

        exec('anytopnm ' . self::IMG_PATH . DIRECTORY_SEPARATOR . $img . ' > ' . self::TMP_PATH . DIRECTORY_SEPARATOR . $time .  '.pnm');

        return $time;
    }

}

Objetos concretos

Nas classes abaixo estão representados os objetos concretos de nossa classe, os produtos que de fato serão servidos ao cliente que está no topo de nosso diagrama. Fiz apenas duas classes de especialização, uma para converter para PNG e outra para converter para JPG, mas você pode adicionar quantas especializações achar necessário.

<?php
class Abstract_Factory_Convert_JPG extends Convert_Abstraction_Factory {

    const EXTENSION = '.jpg';

    public function __construct() {
        parent::__construct();
    }

    public function image_convert($img) {
        $name = $this->to_pnm($img);
        exec('pnmtojpeg ' . self::TMP_PATH . DIRECTORY_SEPARATOR . $name .  '.pnm > ' . self::CONV_PATH . DIRECTORY_SEPARATOR . $name . self::EXTENSION);
    }

}

PNG

<?php
class Abstract_Factory_Convert_PNG extends Convert_Abstraction_Factory {

    const EXTENSION = '.png';

    public function __construct() {
        parent::__construct();
    }

    public function image_convert($img) {
        $name = $this->to_pnm($img);
        exec('pnmtopng ' . self::TMP_PATH . DIRECTORY_SEPARATOR . $name .  '.pnm > ' . self::CONV_PATH . DIRECTORY_SEPARATOR . $name . self::EXTENSION);
    }

}

A Fábrica

Aqui fica o grande truque de nosso script, onde tudo faz sentido. A partir do valor inserido no método contrutor, o script vai decidir qual objeto concreto ele irá usar.

<?php

class Convert_Abstraction_AbstractFactory {

    public function __construct() {

    }

    public static function convert($to) {

        require_once('Convert_Abstraction_Factory.php');

        switch ($to) {
            case 'png':
                require_once 'Convert_Abstraction_Factory_PNG.php';
                $factory = new Abstract_Factory_Convert_PNG();
                break;
            case 'jpg':
                require_once 'Convert_Abstraction_Factory_JPG.php';
                $factory = new Abstract_Factory_Convert_JPG();
                break;
        }

        return $factory;
    }

 }

Instanciando e usando a fábrica criada

<?php

$abstractfactory = new Convert_Abstraction_AbstractFactory();

$factory = $abstractfactory::convert('png');
$factory->image_convert('jpg.jpg')

Padrões de projeto - Introdução

Já se perguntou o que são padrões de projeto? Nesta série, vou explicar por que padrões de projeto são importantes, e quando e por que aplicá-los.

O que são Padrões de Projeto?

Padrões de projeto, mais conhecidos como Design Patterns, são a solução reusável, e otimizados para problemas em nossos programas que encontramos todos os dias. Um padrão de projeto é simplesmente uma classe ou uma biblioteca que você pluga em seu sistema; é muito mais que isso. É um modelo que deve ser implementado usando o bom senso, nas situações corretas. Não é específico de cada linguagem de programação. Um bom padrão de projeto pode ser implementado na maioria - se não em todas - as linguagens de programação, dependendo apenas das capacidades da linguagem escolhida. Mais importante ainda, qualquer padrão de projeto pode ser uma faca de dois gumes, que se implementado de forma incorreta ou no lugar errado, pode ser desastroso e trazer diversos problemas para você. Entretanto, se implementado no lugar certo, no momento certo, pode mudar o rumo do seu projeto, tornando-o muito mais fácil de manejá-lo.

Existem três tipos básico de padrões de projeto. São eles:

Por que devemos usá-los?

Padrões de projeto são, por princípio, soluções bem pensadas para problemas de programação. Muitos programadores encontraram esses problemas anteriormente e usaram essas soluções para remediá-las. Se você encontrou algum desses problemas, por que recriar uma solução se alguém já passou por esses problemas e tem a melhor solução para você?

Ao longo desta série irie falar sobre todos os padrões de projeto, fazendo da mesma forma que foi descrito pela GoF(Gang of Four), apresentado de forma estruturada, dizendo seu nome, seu tipo, definição, estrutura e sua aplicação em código.

Acredito que ao final da série, você terá bagagem o suficiente para criar projetos de qualidade usando padrões de projeto.

Padrões de Projeto Criacionais

Padrões de projeto criacionais são padrões que lidam com o mecanismo de criação de objetos, tentando criar objetos das formas mais adequadas possíveis. A forma básica de criação de objetos pode resultar em problemas ou adicionar complexidades no projeto. Padrões de projeto criacionais, resolvem esses problemas controlando, de alguma forma, a criação desses objetos. Padrões de projeto criacionais ainda são categorizados em padrões criacionais de objetos e padrões criacionais de classes, onde os padrões criacionais de objetos lidam com a criação de objetos, e os de criacionais de classe lidam com a instancialização das classes. De forma resumida, este padrão lida com problemas que podem aparecer na criação e instancialização de objetos.

Alguns exemplos de padrões criacionais são:

  • Abstract factory
  • Factory method
  • Builder pattern
  • Lazy initialization
  • Object pool
  • Prototype
  • Singleton

Padrões de Projeto Estruturais

Padrões de projeto estruturais são padrões que lidam com as estruturas do projeto, facilitando a comunicação entre suas entidades. Por enquanto, esse conceito parmancerá abstrato, mas de acordo com os padrões deste tipo, entenderemos melhor. Em resumo, estes padrões, em outras palavras cuidam da estrutura de seu projeto. Por outro lado padrões estruturais devem ser aplicados em classes responsáveis pela estrutura dos domínios, fazendo uma analogia com a engenharia civil, eles seriam responsáveis por definir o alicerce da construção bem como a estrutura para sustentá-la.

Alguns exemplos de padrões estruturais são:

  • Adapter
  • Bridge
  • Composite
  • Decorator
  • Facade
  • Flyweight
  • Private Class Data
  • Proxy

Padrões de Projeto Comportamentais

Padrões de projeto comportamentais referem-se a identificação de padrões comuns de comunicação entre objetos, tornando-os mais fácil e flexíveis de manipulá-los

  • Chain of responsibility
  • Command
  • Interpreter
  • Iterator
  • Mediator
  • Memento
  • Null Object
  • Observer
  • State
  • Strategy
  • Template method

Tunning - Diminuindo o número de requisições com base64 encoding

Lendo esse artigo hoje, me lembrei que há algum tempo, mentalmente, comecei a escrever algo sobre quando usar e não usar a técnica que usa a imagem codificada em base64 para diminuir o número de requisições ao servidor. Antes de continuarmos, precisamos compreender por alto o que é o base64. Em termos gerais, base64 é uma forma de codificação para qualquer tipo de dado. Neste caso, nós podemos simplificar dizendo que a codificação base64 é a representação textual de uma imagem. Antes de mais nada, é bom lembrar que isso é uma técnica de tunning, e como em grande maioria delas, só é válida em alguns casos específicos. Por exemplo, essa técnica tem maiores ganhos somente quando existe uma quantidade considerável de imagens a serem carregadas em uma página.

Para continuarmos é necessário compreender um pouco sobre como é o passo do carregamento de uma página que contem vários itens a ser carregados. Considere o código abaixo para os próximos exemplos e explicações.

<!DOCTYPE html>
<html dir="ltr">
    <head>
        <meta charset="UTF-8" />
        <title>base64</title></title>
    <script type='text/javascript' src='js.js'></script>
    <link rel="stylesheet" href="css.css" type="text/css" media="screen" />
</head>
<body>
    <div class="image-list">
        <img src="imgs/01.jpg" />
        <img src="imgs/02.jpg" />
        <img src="imgs/03.jpg" />
        <img src="imgs/04.jpg" />
        <img src="imgs/05.jpg" />
        <img src="imgs/06.jpg" />
        <img src="imgs/07.jpg" />
        <img src="imgs/08.jpg" />
        <img src="imgs/09.jpg" />
        <img src="imgs/10.jpg" />
    </div>
</body>
</html>

O código é simples, mas consiste em doze requisições: Um arquivo de estilo, outro de javascript e mais dez requisições para cada imagem que será anexes-coada ao documento. Fiz com dez para não criar um arquivo monstruoso e não perder tempo. A primeira coisa que será carregada do documento acima será o arquivo javascript, mas o browser não pára para analizá-lo para depois depois ir para o próximo item, que seria o arquivo de estilo. Ao ler o documento, o browser vai fazer cada requisição de cada vez, o que pode ser perigoso, caso algum item do seu cabeçalho dê algum problema, o carregamento da sua página pode ser comprometido. Sabendo disso, que tal deixar a cargo do browser apenas duas requisições, e as outras dez serem feitas internamente pelo sistema operacional? Na prática, o que iremos fazer com essa técnica é pegar o conteúdo da imagem, criptografar em base64 e incluí-la no código fonte. A ferramenta de codificação e tradução base64 está implementada em diversas linguagens(python e ruby), e aqui neste exemplo vou utilizar em PHP.

O primeiro passo que irei fazer é codificar uma classe que me retorne a url codificada em base64 e que seja compatível com o que o browser espera. O formato é:

data:[<mime type>][;charset=<charset>][;base64],<encoded data>

c

<?php

final class DataUri {

  protected $file;

  public function __construct($file) {
    $this->file = $file;

    return $this;
  }

  public function generate() {
    if (file_exists($this->file)) {
      return $this->make_uri();
    } else {
      return false;
    }
  }

  private function make_uri() {
    return 'data:'
            . $this->get_mime()
            . ';base64,'
            . base64_encode(file_get_contents($this->file));
  }

  private function get_mime() {
    $info = new finfo(FILEINFO_MIME);

    return $info->file($this->file);
  }

}

$uri = new DataUri('./imgs/gluttony.jpg');
print $uri->generate();

O código acima, quando executado de forma correta, vai gerar as data uri no formato esperado. Veja o exemplo de uma uri gerada. Se você copiar e colar o código abaixo na sua barra de endereço, verá o resultado aqui.

Agora vamos criar o código que vai exibir todas as imagens de um determinado diretório e aplicar nossa técnica.

<?php require_once 'DataUri.php'; ?>
<!DOCTYPE html>
<html dir="ltr">
  <head>
    <meta charset="UTF-8" />
    <title>base64</title></title>
    <script type='text/javascript' src='js.js'></script>
    <link rel="stylesheet" href="css.css" type="text/css" media="screen" />
  </head>
  <body>
    <div class="image-list">
    <?php
      $dir = './imgs/';
      $iterator = new DirectoryIterator($dir);
      foreach ($iterator as $fileinfo) {
        if ($fileinfo->isFile()) {
          $uri = new DataUri($dir. $fileinfo->getFileName());
          echo '<img src="' . $uri->generate() . '" />' . PHP_EOL;
        }
      }
    ?>
    </div>
  </body>
</html>