pesquisa, ping, pubsub, pubsubhub, PubSubHubbub

06 de setembro de 2009 por Prashant · Comentários
Arquivado em: tecnologia

Caso você esteja cético, há um método na loucura acima, no título do post. Em círculos de tecnologia é pouco provável que você nunca ouviu falar de PubSubHubbub. Em rápidas meses, tem sido um dos três primeiros falou sobre as coisas. Outros dois são a criptografia homomórfica e Google onda [ 1. ]. Voltando ao posto atual - termos no título indique como obter o conteúdo de outras pessoas. Seguintes detalhes tornam-se mais claro, se você imaginar as coisas acontecendo no que diz respeito aos blogs, mesmo que eles não são conceitualmente restrito a blogs.

Polling refere-se ao cenário onde os clientes continuam perguntando o servidor se algo de novo surgiu. Quantas vezes para pedir atualizações será sempre um problema com votação muito freqüente ou muito freqüente, mas como um leitor apontou aqui que uma coisa grande, com pesquisas é que o servidor não precisa manter o estado.

Ping refere-se ao caso em que quando postar um artigo, você (ou seu software) também atualiza alguns populares serviços (central) de atualização. Alguns fundo aqui .

Em seguida é pubsub que significa publish / subscribe, um dos primeiros passo para isso foi feito aqui por Evan Henshaw-Plath e Kellan Elliott-McCrea (72 slides, mas vale a pena ir through). Exemplo convincente deram contra era isso - em uma data específica, Friendfeed rastreado Flickr 2,9 milhões de vezes para obter as últimas fotos de 45,754 usuários, dos quais 6.721 tinham visitado Flickr nessas 24 horas e poderia ter 'potencialmente' upload de uma foto. Note-se que o que eles propuseram não era uma nova tecnologia, como eles apontam "nova e revolucionária tecnologia de 20 anos". Se fazê-lo para blogs, em seguida, um dos principais problemas com XMPP - sobrecarga presença de dados, que pode ser tão elevada como 60-70% pode ser muito reduzida.

pubsubhub está para publicar hub subscribe e PubSubHubbub é um protocolo, o núcleo do que é idéia de pubsubhub. Editores em que (dizem blogueiros) atualizar o hub que (pode ser mais de um cubos, que falam entre si) reside "em algum lugar na nuvem", conforme o protocolo que pode ser empurrar ou puxar de acordo com o protocolo, mas o próximo elo na hub cadeia, para o cliente (digamos leitores) é sempre empurrar modelo. Esta página é bom ponto de partida para PubSubHubbub, slides visão geral são boas. Sempre eloqüente Anil Dash descreve aqui como botão web.
Duas outras leituras relacionadas são webhooks que é basicamente callbacks http. Github utiliza -lo, o mesmo acontece com paypal para notificações assíncronas de pagamento no IPN . Assim como muitos outros. Conceito relacionado é rssCloud que é novo hub pubsub. Siga este link para mais detalhes.

Você pode estar se perguntando qual é o ponto de escrever tudo isso aqui, há dois 1. Estas coisas valem a pena conhecer, minimamente, pelo menos, e 2. Este blog é PubSubHubbub habilitado agora via appspot hub usando este wordpress plugin de consumo humano e animal também é PubSubHubbub habilitado via feedburner link, aqui
-
[ 1 ]. - Bom introdutório ler para criptografia totalmente homomórfica é este artigo por Bruce Schneier e essa conversa é mais ou menos única fonte para a onda do Google.

-UPDATE - Este post explica como a exigência de servidor público para retorno de chamada pode ser contornado para clientes desktop usando portal xmpp (para PubSubHubbub).

Um pouco de montagem

29 de agosto de 2009 por Prashant · Comentários
Arquivado em: tecnologia

Depois de ler este artigo sobre buffers Lock Free e vendo o uso de CAS (comparar e trocar), me senti como postar o código assembly para fazer o mesmo. Use caso ali era escrever um método nativo e chamá-lo de Java (de volta em 1,5, quando as estruturas de dados concorrentes em Java eram mais ou menos não existe). Sem mais delongas, eu vou liberar o código para você :) . O primeiro é para a CAS ea segunda é para a computação GCD usando o algoritmo de Euclides (este pode ser encontrado em muitos lugares e tutoriais bem).

Compilar e executar instruções gcc file_name.c ; ./a.out

Compare e Swap

   # Include 
  # Include 
 / / Troca - newvalue, comperand é velho / valor esperado
 / *
  * Função realmente faz a coisa seguinte - se o valor no * dest é igual a OldValue, em seguida, substituí-lo por newvalue mais deixá-lo inalterado: não tudo isso atomicamente
  *
  * Há duas opções para o valor de retorno
  * O valor inicial de 1.is * dest e deixam o ônus da fxn chamando a compará-lo com oldval
  * 2.  fazê-lo por aqui e retornar 0 ou 1, esta deve ser mais eficiente
  ** /

 / * Depois transformá-lo em macro * /
 cas int (int * dest, int OldValue, int newvalue) {
	 printf ("(% d,% d,% d)", * dest, OldValue, newvalue);
	 / * Int cas (int dest, int OldValue, int newvalue) {/ *
	 / * Int cas (int dest, int newvalue, int OldValue) {/ *
	 int resultado = 1 ;/ * 1 mostra que cas conseguiram e 0 mostra que ele falhou * /
	 / * Btw precisa definir cc para sobrepor bandeira!  * /
	 volatile__ __ __asm__ (
			 "Movl% 2,%% eax \ n \ t"
			 "Movl% 3,%% ebx \ n \ t"
			 "0% movl%% ecx \ n \ t"
			 "LOCK \ n \ t"
			 "Cmpxchg ebx%%, (%% ecx) \ n \ t" / * deve bloquear ser na mesma linha * /
			 "Jz FEITO \ n \ t"
			 "Movl $ 0,% 1 \ n \ t"
			 "FEITO: \ n \ t"
			 : "= M" (dest), "= g" (resultado)
			 : "G" (OldValue), "g" (newvalue), "m" (dest)
			 : "% Eax", "% ebx", "ecx", "cc"
			 );
	 printf ("(% d,% d,% d)", * dest, OldValue, newvalue);
	 resultado de retorno;
 }

 / * TODO
  * Escrever outro fxn asm que coloca acima fxn em um loop while e continuar tentando, a menos que ele consegue * /

 int main () {
	 int a = 5, b = 6;
	 int * c = (int *) malloc (sizeof (int));
	 * C = 6;
	 / * Int c = 6; * /
	 printf ("% d \ n", cas (c, b, b));
	 printf ("% d \ n", cas (c, b, a));
	 printf ("% d \ n", cas (c, a, a));
	 printf ("% d \ n", cas (c, b, b));
	 * C = 6;
	 / * C = 5; * /
	 printf ("valor de troca de c * a% d \ n", * c);
	 printf ("% d \ n", cas (c, b, b));
	 printf ("% d \ n", cas (c, b, a));
	 printf ("% d \ n", cas (c, a, a));
	 printf ("% d \ n", cas (c, a, b));
	 printf ("% d \ n", cas (c, b, a));
	 retornar 0;
 }

Notas de formatação - parece marcação de sintaxe wp está adicionando no final, ignorar isso.

GCD

 # Include 
 int mdc (int a, int b) {
     int resultado;
     / * Compute Máximo divisor comum usando o algoritmo de Euclides * /
     volatile__ __asm__ __ ("movl% 1,%% eax;"
                           "Movl% 2,%% ebx;"
                           "Cont.: cmpl $ 0,%% ebx;"
                           "Je FEITO";
                           "Xorl%% edx,% edx%;"
                           "Idivl%% ebx;"
                           "Ebx movl%%%% eax;"
                           "Movl% edx%, ebx%%";
                           "Jmp cont.;"
                           "FEITO: movl% eax%, 0%;": "= g" (resultado): "g" (a), "g" (b)
     );

     resultado de retorno;
 }

 int main () {
     int primeiro, segundo;
     printf ("Entre com dois inteiros:");
     scanf ("% d% d", e em primeiro lugar, e segundo);

     printf ("GCD de% d &% d é% d \ n", primeiro, segundo, mdc (primeiro, segundo));

     retornar 0;
 }

ruby forros para criar um hash de

20 de agosto de 2009 por Prashant · Comentários
Arquivado em: tecnologia

Ontem ao atravessar um dos meus programas antigos, encontrei este escrito por mim algum tempo atrás:

#begin magic
hash=Hash[*CGI.unescape(raw_text).split('&').map{|x| b=x.split("=");b.push(nil) if b.size==1;b}.flatten]
#end magic

Para matar um pouco de suspense, deixe-me revelar que raw_text parece

 

, Direito que foi cortado da confirmação de pagamento paypal.

Acima da linha se quebrado em partes lê melhor:

  unescaped_array = CGI.unescape (raw_text). split ('&')
   unescaped_array = unescaped_array.collect {| x | b = x.split ("="); b.push (zero) se b.size == 1; b}
   flattened_array = unescaped_array.flatten
   hash = Hash [* flattened_array] 

Vamos fazer os passos individuais no irb:

  irb (main):. 009:0> = unescaped_array CGI.unescape (raw_text) split ('&')    

 => ["SUCESSO", "mc_gross = 10,00", "protection_eligibility = inelegíveis", "payer_id = U7PPJJ4TSJ47E", "imposto = 0,00", "payment_date = 09:45:30 10 de julho de 2009 PDT", "payment_status = Pendente "]                                                                         

 irb (main): 013:0> = unescaped_array unescaped_array.map {| x | b = x.split ("="); b.push (zero) se b.size == 1; b}  

 => [["SUCESSO", nil], ["mc_gross", "10,00"], ["protection_eligibility", "não elegíveis"], ["payer_id", "U7PPJJ4TSJ47E"], ["imposto", "0.00"] , ["payment_date", "09:45:30 10 de julho de 2009 PDT"], ["payment_status", "Pendente"]]                               

 irb (main): 014:0> = flattened_array unescaped_array.flatten     

 => ["SUCESSO", nil, "mc_gross", "10,00", "protection_eligibility", "não elegíveis", "payer_id", "U7PPJJ4TSJ47E", "imposto", "0.00", "payment_date", "09:45: 30 10 de julho de 2009 PDT "," payment_status "," Pendente "]
 irb (main): 015:0>
 hash = Hash [* flattened_array]
 => {"Imposto" => "0,00", "payment_status" => "Pendente", "payer_id" => "U7PPJJ4TSJ47E", "mc_gross" => "10,00", "SUCESSO" => nil, "payment_date" = > "09:45:30 10 de julho de 2009 PDT", "protection_eligibility" => "não elegíveis"} 

BTW, * é chamado de operador splat em ruby

Outra maneira de criar hash de "matriz de pares 'é usar injetar:

  hash = [[1,2], [3,4]] injetar ({}). {| resultado, elemento | resultado [element.first] = result [element.last];} resultado 

Não é mais uma maneira :) Escreva um loop, que eu vou deixar como um exercício para os leitores!

Aqui está um caso de uso pouco independente de criação de hash a partir de matrizes:

  irb (main): 005:0> [1,2,3,4,7,9] group_by {| x | x <5.?  : Menor :: maior}

 => {: Menor => [1, 2, 3, 4],: maior => [7, 9]} 

Você pode fazer mais coisas, basicamente resultado do bloco é usado como a chave para esse elemento no hash resultante.

correção gmail, mutt e msmtp

17 de agosto de 2009 por Prashant · Comentários
Arquivado em: tecnologia

Se você usa o mutt e SMTP para acessar o Gmail. Aqui está uma notícia (ruim). Rapaziada do Google mudou novamente certificado. Oh, se você perguntar - como ele sabe? Mutt simples começou a reclamar sobre o certificado mal ao tentar usar msmpt, infame "msmtp: verificação do certificado TLS falhou:. O certificado não tem um emissor conhecido" cumprimentou-me na tela.

Para cruzar confirmar -
Basta executar o seguinte

$ msmtp --serverinfo --host=smtp.gmail.com --tls=on --port=587 --tls-certcheck=off

No lugar do Servidor Thwate velho agora você se seguindo no segmento emissor
Issuer:
Common Name: Google Internet Authority
Organization: Google Inc
Country: US

Felizmente correção é simples, aqui está o que você precisa fazer no debian

# apt-get install ca-certificates
# dpkg -s ca-certificates|grep Version
Version: 20090814

Após isso apenas alterar a linha seguinte em você ~ /. Msmtprc

tls_trust_file /certs/Thawte SSLWeb Server Roots/thawte Premium Server CA/Thawte Premium Server CA.pem

tls_trust_file /certs/Thawte SSLWeb Server Roots/thawte Premium Server CA/Thawte Premium Server CA.pem

para

tls_trust_file /usr/share/ca-certificates/mozilla/Equifax_Secure_CA.crt

Mesclando hashes em conf yaml

31 de julho de 2009 por Prashant · Comentários
Arquivado em: tecnologia

YAML é bastante útil para gravação de arquivos de configuração. Principal vantagem é que, lê-se como arquivo de texto. Isso funciona muito bem se o seu arquivo de configuração é plana (sem hierarquia) e não tem repetições.
Se o seu arquivo de configurações tem repetições, então faz sentido para separar esses elementos e reutilizá-los. O que quero dizer é isso - vamos dizer que você seu arquivo de configuração parecida com esta:

  desenvolvimento:
   input_location: common_input
   output_location: dev_location
   mail:
     smtp_server: Your_Server
     login: your_login
     senha: top_secret
 produção:
   input_location: common_input
   output_location: dev_location
   mail:
     smtp_server: Your_Server
     login: your_login
     senha: top_secret 

Supondo que o código acima em / tmp / test.yml aqui está como você pode ler em python e ruby
$cat readyml.py

 #! / Usr / bin / env python
 de pprint pprint importação em pp
 # No debian precisa instalar python-yaml
 yaml de importação, despejo load_all carga,
 hash = carga (open ('/ tmp / test.yml'))
 pp (hash ['desenvolvimento']) 


$ cat readyml.rb

  #! / Usr / bin / env ruby
 require 'pp'
 hash = YAML :: load (File.open ('/ tmp / test.yml'). ler)
 de hash pp ['desenvolvimento'] 

aqui é um forro de uma mão para a versão ruby
$ ruby -rpp -e 'pp YAML::load(File.open("/tmp/a.yml"))["development"]' ou você pode tentar o mesmo em irb ou console python.

Note-se que no trecho de código acima, tudo é diferente do local de saída é a mesma no desenvolvimento e na parte de produção. Este é o lugar onde identificador do nó yml vem resgatar. Idéia é simples ter um conjunto de valores padrão e substituí-los em lugar diferente.
Você pode puxá-lo para além da seguinte forma:

  padrões e padrões:
   input_location: common_input
   output_location: dev_location
   mail:
     SENDER_NAME: remetente
     smtp_server: Your_Server
     login: your_login
     senha: top_secret
 desenvolvimento:
   <<: * Os padrões
 produção:
   <<: * Os padrões
   output_location: prod_location 


$ ruby -rpp -e 'pp YAML::load(File.open("/tmp/a.yml"))["development"]["mail"]["login"]'
"your_login"
$

Grande, ele funciona (tm)!.
Provavelmente nós trocamos um pouco de clareza para um pouco de magia. Aqui está uma pequena explicação: &, * e <<: & que é marca de âncora pode ser entendida como identificador de nó, * é nó de referência e <<: representa a junção de hash.

Para mais detalhes veja tanto especificações yaml ou wikipedia
Até aí tudo bem, mas há um problema aqui, estas fusões de hash não são recursivas. O que isso significa é o seguinte: digamos que você quer ter nome de remetente diferente para o correio em dois ambientes, você pode ser tentado a fazer o seguinte:

  padrões e padrões:
   input_location: common_input
   output_location: dev_location
   mail:
     SENDER_NAME: remetente
     smtp_server: Your_Server
     login: your_login
     senha: top_secret
 desenvolvimento:
   <<: * Os padrões
   mail:
     SENDER_NAME: sender_dev
 produção:
   <<: * Os padrões
   output_location: prod_location
   mail:
     SENDER_NAME: sender_prod 

Vamos verificar

$ ruby -rpp -e 'pp YAML::load(File.open("/tmp/a.yml"))["development"]["mail"]["login"]'
nil
$

Opa, algo deu errado, como já mencionado problema é que a junção de hash não é recursivo e enquanto fundindo-substituído e-mail de incumprimento por e-mail da produção que tem apenas uma chave. Solução / trabalho em torno é para desenrolar mais um nível:

  common_settings: & common_settings
 input_location: common_input
 output_location: dev_location
 mail_defaults: & mail_defaults
  SENDER_NAME: remetente
   smtp_server: Your_Server
   login: your_login
   senha: top_secret

 padrões e padrões:
   <<: * Common_settings
   mail:
     <<: * Mail_defaults
 desenvolvimento:
   <<: * Os padrões
 produção:
   <<: * Os padrões
   mail:
     <<: * Mail_defaults
     SENDER_NAME: sender_prod

Vamos verificar novamente

$ ruby -rpp -e 'pp YAML::load(File.open("/tmp/a.yml"))["development"]["mail"]["login"]'
"your_login"
$

Será que você diz que tem um nível de aninhamento mais, bem, você pode definitivamente desenrolar mais um nível, mas depois torna-se uma bagunça. Então, se você não está tentando escrever solução para torres de Hanói em um arquivo conf, é melhor restucture arquivo conf de cavar yaml ou qualquer outra coisa. Mas isso é a chamada de qualquer maneira.

Um pouco de redirecionamento de shell

10 de maio de 2009 por Prashant · Comentários
Arquivado em: tecnologia

Aqui está como fazemos normalmente redirecionamento shell
$ ./pgm.sh args >out.txt 2>err.txt
Eu queria modificar um pouco e executado da seguinte forma
$ ./pgm.sh args
com a exigência de que a saída de erro e deve ir para algum nome calculado dentro pgm.sh com base em argumentos. Um caso ilustrativo poderia ser quando a data é parte de args. Então você gostaria de ir stdout para dizer / o diretório / / pgm_out_YYYYMMDD.txt 1

O problema com a maneira padrão de redirecionar N>file.txt ou seja, associando arquivo descritor de N para file.txt, é que ele funciona apenas para o processo recém-bifurcada e não para o processo atual.
assim
$ echo hi 1>out.txt ; echo hii . enviará oi para out.txt mas irá imprimir hii para stdout 2

Este é o lugar onde exec vem em nosso socorro. Se somarmos exec 1>somefile.txt , em seguida, saída do resto do script irá para o arquivo.txt

$ cat test.sh
#!/usr/bin/env bash
exec 1>out.txt
echo hi
echo hii
$. / Test.sh irá redirecionar oi, bem como a hii out.txt

Da mesma forma para redirecionar stdout stderr, assim como nós vamos fazer algo assim
cat test2.sh
exec 1>out.txt
exec 2>err.txt
echo out text
echo 1>&2 err text
somenoneexitent command
ls -ld /tmp

Agora, voltando ao ponto original de redirecionar para algum arquivo de dentro da casca, digamos programa de computado o nome do arquivo em algum OUTFILE variável, poderíamos ter acabado de fazer exec 1>$OUTFILE

Isso resolve o problema atual. Mas você pode gostar de ir por exemplo a seguir que atinge "acesso aleatório" do arquivo em shell script. Exemplo é a partir daqui
echo 1234567890 > File # Write string to "File".
exec 3<> File # Open "File" and assign fd 3 to it.
read -n 4 <&3 # Read only 4 characters.
echo -n . >&3 # Write a decimal point there.
exec 3>&- # Close fd 3.
cat File # ==> 1234.67890

Com os comentários, este código é auto-explicativo.
-
1 Também pode ser feito por $ ./pgm.sh args >pgm_out`date +%Y%m%d` mas a idéia é gerar esse nome de arquivo com base em alguma lógica no próprio programa.
2 1 em 1> out.txt é redundante, mas esclarece que aqui estamos redirecionando fd 1

Para dimensionar ou não para escalar

11 de janeiro de 2009 por Prashant · Comentários
Arquivado em: tecnologia

Ao falar sobre o particionamento horizontal de bases de dados, DHH de ROR fama sugere que o material de escala pode esperar, definitivamente, esperar até que ponto as suas necessidades de negócios exigem. Seu artigo definitivamente faz sentido para configurações pequenas startups dizer. Não quer dizer que em startups que você deve escrever programas de demonstração, mas uma vez que existem apenas 24 horas em um dia você deve se concentrar em servir dizer 1000 usuários de modo mais satisfatório do que perder o sono por se preocupar como vai meu pedido de lidar com a carga de 13.142 mil usuários. Se você receber esses usuários muitas você vai saber como escalar. Para escalabilidade startups é um problema bom para resolver um problema, mas muito melhor ter, quero dizer, qualquer inicialização adoraria ter esse problema!

Em outra relacionada artigo Jeremy Zawodny escreve você não deve depender de Moore se você tem problemas de escalabilidade.

Uma vez que esses artigos se referem a lei de Moore não posso deixar de escrever que a lei de Moore deve ser uma das lei mais generalizada em Ciência da Computação. De sua previsão original sobre densidade transistor, esta lei agora é citado em qualquer lugar você se deparar com um crescimento exponencial.