pesquisa, ping, pubsub, pubsubhub, PubSubHubbub
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
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
# Includeint 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
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
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
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
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
$. / Test.sh irá redirecionar oi, bem como a hii out.txt
$ cat test.sh
#!/usr/bin/env bash
exec 1>out.txt
echo hi
echo hii
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
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.



































