
Bem, não é que esteja a usar a frase no seu sentido mais clássico mas acho que é algo apropriada ao que acabei de passar com MAIS uma experiência a programar com APIs da Microsoft!
Estou a trabalhar num projecto com o Microsoft Windows HPC 2008 (aliás, já o estou há quase 2 anos) e surgiu a necessidade de controlar jobs submetidos directamente pelo HPC Job Manager, pela command prompt ou até programaticamente.
Ora, se controlar jobs que nós mesmos criamos é relativamente fácil, a coisa complica-se aqui! :o)
A solução inicial passou por definir um ActivationFilterProgram através do cluscfg.
Embora isto dê muito jeito para evitar que os jobs submetidos directamente ao Windows fossem executados de imediato pelo scheduler da Microsoft, não me resolvia o outro problema: como mudar parametros de jobs que não me pertencem?!
Ora a solução foi também relativamente simples: ISchedulerJob.CloneJob()!
A ideia era clonar um job sempre que este fosse directamente submetido (sem passar pela minha aplicação) de forma a poder controlar todos os seus aspectos quando precisasse.
O problema é que hoje descobri que isto também não é solução já que o ISchedulerJob.CloneJob() só funciona SE o utilizador que está a chamar este método for o Owner do job a clonar!
Azar do caraças...de volta ao quadro de sketches! ;o)
A solução final parecia também ser relativamente simples: fazer um método CloneJob() que criasse um novo job e copiasse todos os atributos do job original!
É claro que isto funciou às mil maravilhas! Até chegar à altura de executar o job clonado... :o)
A principio pensei que fosse apenas uma confirmação que o ser humano ainda não controla por completo o milagre da vida e o cloning é algo que deve apenas ser deixado para Deus! Mas não...afinal o problema era bastante mais bizarro :o)
Os jobs clonados falhavam com uma razão mais ao menos como esta: "Failed Task jobID.TaskID: task exit with exit code 0".
Ora, coisa estranha esta hein? E eu que sempre pensei que uma aplicação, método ou função que retorne 0 signfica que tudo correu bem? :o)
Parece que, mais uma vez, a Microsoft quer redefinir o que já está definido (por eles mesmo)!
Não há crise nenhuma, é só uma questão de verificar tudo de novo até funcionar, correcto?
Certo! E de acordo com a documentação da Microsoft, o método ISchedulerJob.CloneJob() deles copia nada mais que 52 atributos (ou serão 51 e eu contei mal)?
É claro que, para ajudar, a documentação tinha de estar desactualizada, algumas das variáveis não existirem (ou serem privadas) e terem os nomes desactualizados :o)
Isso também não foi desmotivador o suficiente para mim que testei esses 52 atributos, um a um, até perceber o que estava a acontecer para o job clonado falhar.
Depois de verificar que TODOS os atributos eram copiados exactamente com o mesmo valor, foi preciso continuar com a análise empírica para tentar perceber qual dos valores estava a dar asneira.
Nada mais simples: comenta, recompila, reinstala e testa! (isto para cada um dos atributos)
Cheguei a um ponto onde FINALMENTE descobri o que estava a causar este estranho problema (afinal não eram os meus fracos dotes na área da genética)!
Ora, as Tasks podem especificar quais os ficheiros para usar como stdout, stdin e stderr e o problema estava exactamente aqui!
Não é que o bixo, embora quando se crie um job as propriedades stdoutFilePath, stdinFilePath e stderrFilePath sejam TODAS "" por definição, o gajo dá asneira se atribuirmos o valor ""? :o)
Ou seja, o código que estava a meter nojo era:
clonedTask.stdinFilePath = originalTask.stdinFilePath;
clonedTask.stdoutFilePath = originalTask.stdoutFilePath;
clonedTask.stderrFilePath = originalTask.stderrFilePath;
Embora todas estas propriedades sejam inicializadas durante a criação do job com "", se tentarmos atribuir-lhes QUALQUER valor (ie: ""), o sacana do Scheduler assume que estamos a pedir para usar um ficheiro stdout / stdin / stderr na path "".
Para concluir, a solução para TODO este trabalho foi deveras simples:
if (!originalTask.stdinFilePath.equals(""))
clonedTask.stdinFilePath = originalTask.stdinFilePath;
if (!originalTask.stdoutFilePath.equals(""))
clonedTask.stdoutFilePath = originalTask.stdoutFilePath;
if (!originalTask.stderrFilePath.equals(""))
clonedTask.stderrFilePath = originalTask.stderrFilePath;
Isto tudo para concluir a frase inicial do título deste post: The cake is a lie!
NUNCA confiem na documentação e APIs da Microsoft :o)
Estou a trabalhar num projecto com o Microsoft Windows HPC 2008 (aliás, já o estou há quase 2 anos) e surgiu a necessidade de controlar jobs submetidos directamente pelo HPC Job Manager, pela command prompt ou até programaticamente.
Ora, se controlar jobs que nós mesmos criamos é relativamente fácil, a coisa complica-se aqui! :o)
A solução inicial passou por definir um ActivationFilterProgram através do cluscfg.
Embora isto dê muito jeito para evitar que os jobs submetidos directamente ao Windows fossem executados de imediato pelo scheduler da Microsoft, não me resolvia o outro problema: como mudar parametros de jobs que não me pertencem?!
Ora a solução foi também relativamente simples: ISchedulerJob.CloneJob()!
A ideia era clonar um job sempre que este fosse directamente submetido (sem passar pela minha aplicação) de forma a poder controlar todos os seus aspectos quando precisasse.
O problema é que hoje descobri que isto também não é solução já que o ISchedulerJob.CloneJob() só funciona SE o utilizador que está a chamar este método for o Owner do job a clonar!
Azar do caraças...de volta ao quadro de sketches! ;o)
A solução final parecia também ser relativamente simples: fazer um método CloneJob() que criasse um novo job e copiasse todos os atributos do job original!
É claro que isto funciou às mil maravilhas! Até chegar à altura de executar o job clonado... :o)
A principio pensei que fosse apenas uma confirmação que o ser humano ainda não controla por completo o milagre da vida e o cloning é algo que deve apenas ser deixado para Deus! Mas não...afinal o problema era bastante mais bizarro :o)
Os jobs clonados falhavam com uma razão mais ao menos como esta: "Failed Task jobID.TaskID: task exit with exit code 0".
Ora, coisa estranha esta hein? E eu que sempre pensei que uma aplicação, método ou função que retorne 0 signfica que tudo correu bem? :o)
Parece que, mais uma vez, a Microsoft quer redefinir o que já está definido (por eles mesmo)!
Não há crise nenhuma, é só uma questão de verificar tudo de novo até funcionar, correcto?
Certo! E de acordo com a documentação da Microsoft, o método ISchedulerJob.CloneJob() deles copia nada mais que 52 atributos (ou serão 51 e eu contei mal)?
É claro que, para ajudar, a documentação tinha de estar desactualizada, algumas das variáveis não existirem (ou serem privadas) e terem os nomes desactualizados :o)
Isso também não foi desmotivador o suficiente para mim que testei esses 52 atributos, um a um, até perceber o que estava a acontecer para o job clonado falhar.
Depois de verificar que TODOS os atributos eram copiados exactamente com o mesmo valor, foi preciso continuar com a análise empírica para tentar perceber qual dos valores estava a dar asneira.
Nada mais simples: comenta, recompila, reinstala e testa! (isto para cada um dos atributos)
Cheguei a um ponto onde FINALMENTE descobri o que estava a causar este estranho problema (afinal não eram os meus fracos dotes na área da genética)!
Ora, as Tasks podem especificar quais os ficheiros para usar como stdout, stdin e stderr e o problema estava exactamente aqui!
Não é que o bixo, embora quando se crie um job as propriedades stdoutFilePath, stdinFilePath e stderrFilePath sejam TODAS "" por definição, o gajo dá asneira se atribuirmos o valor ""? :o)
Ou seja, o código que estava a meter nojo era:
clonedTask.stdinFilePath = originalTask.stdinFilePath;
clonedTask.stdoutFilePath = originalTask.stdoutFilePath;
clonedTask.stderrFilePath = originalTask.stderrFilePath;
Embora todas estas propriedades sejam inicializadas durante a criação do job com "", se tentarmos atribuir-lhes QUALQUER valor (ie: ""), o sacana do Scheduler assume que estamos a pedir para usar um ficheiro stdout / stdin / stderr na path "".
Para concluir, a solução para TODO este trabalho foi deveras simples:
if (!originalTask.stdinFilePath.equals(""))
clonedTask.stdinFilePath = originalTask.stdinFilePath;
if (!originalTask.stdoutFilePath.equals(""))
clonedTask.stdoutFilePath = originalTask.stdoutFilePath;
if (!originalTask.stderrFilePath.equals(""))
clonedTask.stderrFilePath = originalTask.stderrFilePath;
Isto tudo para concluir a frase inicial do título deste post: The cake is a lie!
NUNCA confiem na documentação e APIs da Microsoft :o)
0 comments:
Post a Comment