Exemple #1
0
 def claims(self, q):
     '''claims($q): show claims established by query q'''
     cs = terms.loads(self.etb().query_claims(q))
     self.print_claims(cs, 'established by query %s' % q)
     if len(cs) == 1:
         return terms.dumps(cs[0])
     else:
         return [terms.dumps(c) for c in cs]
Exemple #2
0
    def interpret_goal_somewhere(self, goal, internal_goal):
        """Interpret the goal on some node, possibly this one."""
        pred = goal.first_symbol()
        self.log.debug('Looking to interpret %s somewhere.' % pred)
        candidates = self.networking.neighbors_able_to_interpret(pred)
        link = False
        if not candidates:
            candidates = self.networking.links_able_to_interpret(pred)
            link = True
            if not candidates:
                self.error("no node able to interpret goal {0}".format(goal))

        argspecstr = candidates[0].predicates[str(pred.val)]
        argspecs = wrapper.ArgSpec.parse(argspecstr)
        if len(argspecs) != len(goal.args):
            self.error(
                "Have %d argspecs, expect %d" % (len(argspecs), len(goal.args)))

        handles = []
        for (spec, arg) in zip(argspecs, goal.args) :
            if spec.kind == 'handle':
                handles.append((spec, arg))

        candidates = self.filter_candidates(candidates, goal)
        if not candidates:
            self.error("no node able to interpret goal {0}".format(goal))

        best_node = min(candidates, key=lambda n: n.load)
        # adding internal goal: this needs to be added for remote evaluation
        if best_node.id == self.id :
            self.interpret_state.interpret(goal, internal_goal, sync=True)
            return

        argspecstr = best_node.predicates[str(goal.first_symbol().val)]
        argspecs = wrapper.ArgSpec.parse(argspecstr)
        new_id = uuid.uuid4().get_hex()
        self.active_remote_queries[new_id] = (goal, best_node, argspecs, goal)
        proxy = best_node.proxy
        
        if link:
            self.log.info('Sending %s to remote ETB on %s' % (goal.first_symbol(), best_node.id))
            proxy.interpret_goal_remotely(self.id, terms.dumps(goal), new_id)
        else:
            self.log.info('Asking {0} to interpret {1}.'
                          .format(best_node.id, goal.first_symbol()))
            proxy.interpret_goal(self.id, terms.dumps(goal), new_id)
        
        best_node.increment_load()
Exemple #3
0
 def task_interpret(etb, query_id=query_id, goals=goals):
     query = self.etb.create_query((goals,))
     self.query_wait(query)
     answer = terms.dumps(self.etb.query_answers(query))
     def task(etb, query_id=query_id, answer=answer):
         proxy.answer_query(query_id, answer)
     etb.short_pool.schedule(task)
Exemple #4
0
    def get_file(self, src, dst=None):
        '''
        gets the file from the ETB

        src is a file handle
        '''
        if is_filehandle(src):
            if dst is None:
                dst = src['file']
            if isinstance(dst, terms.Const):
                dst = dst.val
            dst = dst.strip('"\'')  # Get rid of outer quote marks
            jsrc = terms.dumps(src)
            contents = self.etb().get_file(jsrc)
            ndir = os.path.dirname(dst)
            if ndir != '' and not os.path.isdir(ndir):
                os.makedirs(ndir)
            with codecs.open(dst, mode='wb', errors='ignore') as fd:
                fd.write(base64.b64decode(contents))
        elif isinstance(src, basestring):
            # Just get whatever version is in the working (Git) directory
            shandle = self.etb().get_filehandle(src)
            handle = json.loads(shandle)
            if is_filehandle(handle):
                return self.get_file(handle, dst)
        else:
            raise TypeError(
                'get_file: string or filehandle expected: {0}: {1}'.format(
                    src, type(src)))
Exemple #5
0
 def task_interpret(etb, query_id=query_id, goals=goals):
     query = self.etb.create_query((goals,))
     self.query_wait(query)
     if False:
         filename = self.etb.engine.goal_deps_to_png(goals)
         os.rename(filename, "%s.png" % goals)
         self.log.debug("answering_png.png for %s dumped to %s" % (goals, os.getcwd()))
     ans = self.etb.query_answers(query)
     answer = terms.dumps(ans)
     self.log.debug('task_interpret: answer to query is: %s' % answer)
     def task(etb, query_id=query_id, answer=answer):
         if from_id in self._neighbors:
             proxy = self.neighbor(from_id).proxy
         else:
             print('setting proxy to None')
             proxy = None
         if proxy is not None:
             self.log.debug('Sending query answer to %s', from_id)
             # I don't know why, but at some point the following
             # started raising the exception printing proxy:
             #   method "__unicode__" is not supported
             #self.log.info('proxy for %s is %s' % (from_id, proxy))
             self.log.debug('_neighbors = %s' % self._neighbors)
             proxy.answer_query(query_id, answer)
     etb.short_pool.schedule(task)
Exemple #6
0
 def query_answers(self, qid):
     """Given a query ID, returns a JSON-encoded list of all current answers
     (substitutions) to the query. The list may grow later, as new claims
     are added to the system.
     """
     answers = self.etb.query_answers(qid)
     if answers:
         return terms.dumps(answers['substs'])
     else:
         return ''
Exemple #7
0
 def link_predicates(self):
     """
     Reveals our ETB network capabilities. Passed as a payload in pokes.
     """
     predicates = self.etb.interpret_state.predicates()
     for n in list(self.neighbors):
         predicates.update(n.predicates)
     response = terms.dumps(predicates)
     #self.log.debug("link_predicates of %s are %s" % (self.id, response))
     return response
Exemple #8
0
 def task(etb, neighbor=neighbor):
     #etb.networking.log.debug('PING')
     if neighbor.proxy is not None:
         predicates = etb.interpret_state.predicates()
         payload = { 'load': etb.load
                   , 'predicates': predicates
                   , 'subscriptions': list(etb.subscriptions)
                   , 'to_hosts': list(neighbor.hosts)
                   , 'tasks': [] #list(etb.active_queries())
                   }
         neighbor.proxy.ping(etb.id, etb.networking.port,
                             neighbor.id, terms.dumps(payload))
Exemple #9
0
    def get_contents_from_somewhere(self, sha1, seen=[]):
        """
        Find the content corresponding to a sha1, don't b64encode it
        (its for local use).  Presupposes it isn't to be had
        locally. Tries each neighbor, then ask any remote link, taking
        care not to chase ones tail.
        """
        contents = None
        execp = False
        self.log.debug('Being asked for contents with sha1 %s' % sha1)
        #do my neighbours have it?
        for n in self.neighbors:
            if n.id != self.id:
                #self.log.debug('Asking for %s from neighbor: %s with proxy %s' % (sha1, n.id, n.proxy))
                self.log.debug('Asking for %s from neighbor: %s' % (sha1, n.id))
                with self._rlock:
                    try:
                        if n.proxy is not None:
                            b64_contents, execp = n.proxy.get_blob(sha1)
                            contents = base64.b64decode(b64_contents)
                            if contents is not None and contents is not '':
                                break
                    except Exception as e:
                        pass

        if contents is not None and contents is not '':
            self.log.debug('My neigbours had %s!' % sha1)
            return contents, execp

        self.log.debug('Not local, asking for %s from my links %s  (seen = %s)' % (sha1, self.links, seen))
        for n in self.links:
            with self._rlock:
                try:
                    if n.proxy is not None and n.id not in seen:
                        visited = list(seen)
                        visited.append(n.id)
                        visited = terms.dumps(visited)
                        self.log.debug('Asking for %s from link: %s with proxy %s (visited = %s)' % (sha1, n.id, n.proxy, visited))
                        b64_contents, execp = n.proxy.get_contents_from_network(sha1, visited)
                        contents = base64.b64decode(b64_contents)
                        if contents is not None and contents is not '':
                            break
                except Exception as e:
                    self.log.debug('Asking for %s from link: %s **THREW** %s'  % (sha1, n.id, e))
                    pass

        if contents is None:
            self.log.error('Could not find file %s', sha1)
        else: 
            self.log.debug('My links had %s!' % sha1)
        return contents, execp
Exemple #10
0
 def get_goals_dependencies(self, goal, remote_etb):
     for a in goal.get_args():
         if a.is_ground():
             try:
                 fileref = { 'file' : str(a.get_args()[terms.mk_stringconst('file')]),
                             'sha1' : str(a.get_args()[terms.mk_stringconst('sha1')]) }
                 content = remote_etb.get_file(terms.dumps(a))
                 if content:
                     content = base64.b64decode(content)
                     self.create_file(content, fileref['file'])
                 else:
                     self.log.error('Unable to get remote file: %s', fileref)
             except Exception as e:
                 # Non-fileref will go there
                 pass
Exemple #11
0
    def query_claims(self, qid):
        """Returns the set of fact answers for this query. It returns a
        JSON-encoded list of lists of terms. Each 'fact' may have one or more
        claims to back it.

        Otherwise, returns False.
        """
        goals = self.etb.get_query(qid)
        if not goals:
            print('Invalid query id: {0}'.format(qid))
            return []
        answers = []
        for goal in goals:
            claims = self.etb.engine.get_claims_matching_goal(goal)
            for claim in claims:
                answers.append(claim.literal)
        return terms.dumps(answers)
Exemple #12
0
 def get_all_claims(self):
     """Get all the claims known by this node, as a JSON list"""
     claims = list(self.etb.engine.get_claims())
     return terms.dumps(claims)
Exemple #13
0
 def get_neighbors(self):
     """Returns, over the network, a JSON list of current neighbors."""
     neighbors = list()
     neighbors = [((n.id, list(n.hosts), n.port, n.timestamp))
                  for n in self.neighbors]
     return terms.dumps(neighbors)
Exemple #14
0
 def find_claims(self, pattern, reasons=False):
     """Find and return claims that match the given pattern.
     See the Python re module for possible patterns."""
     claims = list(self.etb.find_claims(pattern))
     return terms.dumps(claims)
Exemple #15
0
 def all_claims(self):
     self.log.debug('looking for all claims')
     claims = list(self.etb.all_claims())
     return terms.dumps(claims)
Exemple #16
0
 def get_facts(self):
     """Get the list of facts on this node.
     This returns a more readable form of the facts."""
     return terms.dumps(self.etb.engine.facts)
Exemple #17
0
 def get_rules(self):
     """Get the list of rules on this node.
     This returns a more readable form of the rules."""
     return terms.dumps(self.etb.engine.rules)