コード例 #1
0
ファイル: clonesrv6.c プロジェクト: CaiZhongda/zguide
static int
s_collector (zloop_t *loop, zmq_pollitem_t *poller, void *args)
{
    clonesrv_t *self = (clonesrv_t *) args;

    kvmsg_t *kvmsg = kvmsg_recv (poller->socket);
    if (kvmsg) {
        if (self->active) {
            kvmsg_set_sequence (kvmsg, ++self->sequence);
            kvmsg_send (kvmsg, self->publisher);
            int ttl = atoi (kvmsg_get_prop (kvmsg, "ttl"));
            if (ttl)
                kvmsg_set_prop (kvmsg, "ttl",
                    "%" PRId64, zclock_time () + ttl * 1000);
            kvmsg_store (&kvmsg, self->kvmap);
            zclock_log ("I: publishing update=%d", (int) self->sequence);
        }
        else {
            //  If we already got message from active, drop it, else
            //  hold on pending list
            if (s_was_pending (self, kvmsg))
                kvmsg_destroy (&kvmsg);
            else
                zlist_append (self->pending, kvmsg);
        }
    }
    return 0;
}
コード例 #2
0
ファイル: clonesrv5.c プロジェクト: Alex-Benveniste/zguide
//  If key-value pair has expired, delete it and publish the
//  fact to listening clients.
static int
s_flush_single (char *key, void *data, void *args)
{
    clonesrv_t *self = (clonesrv_t *) args;

    kvmsg_t *kvmsg = (kvmsg_t *) data;
    int64_t ttl;
    sscanf (kvmsg_get_prop (kvmsg, "ttl"), "%" PRId64, &ttl);
    if (ttl && zclock_time () >= ttl) {
        kvmsg_set_sequence (kvmsg, ++self->sequence);
        kvmsg_set_body (kvmsg, (byte *) "", 0);
        kvmsg_send (kvmsg, self->publisher);
        kvmsg_store (&kvmsg, self->kvmap);
        zclock_log ("I: publishing delete=%d", (int) self->sequence);
    }
    return 0;
}
コード例 #3
0
/**
 * We call this function for each key-value pair in our hash table
 */
static int
s_send_single (const char *key, void *data, void *args)
{
    kvroute_t *kvroute = (kvroute_t *) args;
    kvmsg_t *kvmsg = (kvmsg_t *) data;
    DEBUG ("I: s_send_single %"PRId64" type:%s", kvmsg_sequence(kvmsg), kvmsg_get_prop (kvmsg, "type") );

    if (strlen (kvroute->subtree) <= strlen (kvmsg_key (kvmsg))
    &&  memcmp (kvroute->subtree,
                kvmsg_key (kvmsg), strlen (kvroute->subtree)) == 0) {
        zframe_send (&kvroute->identity,    //  Choose recipient
            kvroute->socket, ZFRAME_MORE + ZFRAME_REUSE);
        kvmsg_send (kvmsg, kvroute->socket);
    }
    
    return 0;
}
コード例 #4
0
ファイル: clonesrv5.c プロジェクト: Alex-Benveniste/zguide
static int
s_collector (zloop_t *loop, zmq_pollitem_t *poller, void *args)
{
    clonesrv_t *self = (clonesrv_t *) args;

    kvmsg_t *kvmsg = kvmsg_recv (poller->socket);
    if (kvmsg) {
        kvmsg_set_sequence (kvmsg, ++self->sequence);
        kvmsg_send (kvmsg, self->publisher);
        int ttl = atoi (kvmsg_get_prop (kvmsg, "ttl"));
        if (ttl)
            kvmsg_set_prop (kvmsg, "ttl",
                "%" PRId64, zclock_time () + ttl * 1000);
        kvmsg_store (&kvmsg, self->kvmap);
        zclock_log ("I: publishing update=%d", (int) self->sequence);
    }
    return 0;
}
コード例 #5
0
ファイル: collabclientui.c プロジェクト: nthung82/fontforge
/**
 * Process the given kvmsg from the server. If create is set and we do
 * not have any charview for a changed glyph then we first create a
 * charview for it. This allows the updates from a server to be
 * processed at startup time, getting us up to speed with any glyphs
 * that have changed.
 *
 * This function is mainly called in response to an update which is
 * published from the server. However, in sessionJoin() we also call
 * here to handle the incremental updates to glyphs that have occurred
 * after the SFD was sent to the server.
 */
static void zeromq_subscriber_process_update( cloneclient_t* cc, kvmsg_t *kvmsg, int create )
{
    cc->sequence = kvmsg_sequence (kvmsg);
    if( cc->sequence >= cc->roundTripTimerWaitingSeq )
	cc->roundTripTimerWaitingSeq = 0;
		    

    char* uuid = kvmsg_get_prop (kvmsg, "uuid" );
    byte* data = kvmsg_body (kvmsg);
    size_t data_size = kvmsg_size (kvmsg);

    printf("cc process_update() uuid:%s\n", uuid );
    FontView* fv = FontViewFind( FontViewFind_byXUIDConnected, uuid );
    printf("fv:%p\n", fv );
    if( fv )
    {
	if( !data_size )
	{
	    printf("WARNING: zero length message!\n" );
	    return;
	}
			
	SplineFont *sf = fv->b.sf;
	if( !sf )
	{
	    printf("ERROR: font view does not have the splinefont set!\n" );
	    return;
	}
	
	char* pos  = kvmsg_get_prop (kvmsg, "pos" );
	char* name = kvmsg_get_prop (kvmsg, "name" );
	printf("pos:%s\n", pos );
//	SplineChar *sc = sf->glyphs[ atoi(pos) ];
	SplineChar* sc = SFGetOrMakeChar( sf, -1, name );
	
	printf("sc:%p\n", sc );
	if( !sc )
	{
	    printf("WARNING: font view does not have a glyph for pos:%s\n",  pos );
	    printf("WARNING: font view does not have a glyph for name:%s\n", name );
	    return;
	}
	
	printf("sc.name:%s\n", sc->name );
	printf("data.size:%ld\n", data_size );
	if( DEBUG_SHOW_SFD_CHUNKS )
	    printf("data:%s\n", data );
		    
	int current_layer = 0;

	if( !sc->views && create )
	{
	    int show = 0;
	    CharView* cv = CharViewCreateExtended( sc, fv, -1, show );
	    printf("created charview:%p\n", cv );
	}
	
	for( CharViewBase* cv = sc->views; cv; cv = cv->next )
	{
	    printf("have charview:%p\n", cv );
	    
	    char filename[PATH_MAX];
	    snprintf(filename, PATH_MAX, "%s/fontforge-collab-inx-%d.sfd", getTempDir(), getpid() );
	    GFileWriteAll( filename, (char*)data);
	    FILE* file = fopen( filename, "rb" );
	    Undoes* undo = SFDGetUndo( sf, file, sc,
				       "UndoOperation",
				       "EndUndoOperation",
				       current_layer );
	    fclose(file);
	    if( !undo )
	    {
		printf("***** ERROR ****** reading back undo instance!\n");
		printf("data: %s\n\n", data );
	    }
	    if( undo )
	    {
		// NOT HANDLED!
		if( undo->undotype == ut_statehint )
		{
		    printf("*** warning ut_statehint not handled\n");
		    break;
		}
		
		printf("________________________ READ undo.layer: %d  dm:%d layer_sz:%d\n",
		       undo->layer, cv->drawmode, cv->sc->layer_cnt );
		int selectedlayer = cv->drawmode;
		if( undo->layer != UNDO_LAYER_UNKNOWN )
		    selectedlayer = undo->layer;    

		// use oldlayer to store current setting and switch to the
		// selected layer for this block.
		int oldlayer = cv->drawmode;
		cv->drawmode = selectedlayer;
		undo->next = 0;
		undo->next = cv->layerheads[selectedlayer]->redoes;
		cv->layerheads[selectedlayer]->redoes = undo;
		CVDoRedo( cv );

		char* isLocalUndo = kvmsg_get_prop (kvmsg, "isLocalUndo" );
		if( isLocalUndo )
		{
		    if( isLocalUndo[0] == '1' )
		    {
			Undoes* undo = cv->layerheads[selectedlayer]->undoes;
			if( undo )
			{
			    cv->layerheads[selectedlayer]->undoes = undo->next;
			    undo->next = cv->layerheads[selectedlayer]->redoes;
			    cv->layerheads[selectedlayer]->redoes = undo;
			}
		    }
		}

		if( cv->drawmode != oldlayer )
		{
		    cv->drawmode = oldlayer;
		    CVCharChangedUpdate( cv );

		}
		
		
	    }
			    
	    break;
	}
    }
		    
    printf ("I: processed update=%d\n", (int) cc->sequence);
}
コード例 #6
0
FontViewBase* collabclient_sessionJoin( void* ccvp, FontView *fv )
{
    FontViewBase* ret = 0;
    
#ifdef BUILD_COLLAB
    
    cloneclient_t* cc = (cloneclient_t*)ccvp;
    printf("collabclient_sessionJoin(top)\n");

    //  Get state snapshot
    cc->sequence = 0;
    zstr_sendm (cc->snapshot, "ICANHAZ?");
    zstr_send  (cc->snapshot, SUBTREE);

    // if we wait for timeoutMS millisec then we assume failure
    // timeWaitedMS is used to keep track of how long we have waited
    kvmsg_t* lastSFD = 0;
    int timeWaitedMS = 0;
    int timeoutMS = pref_collab_sessionJoinTimeoutMS;
    while (true)
    {
	printf("timeoutMS:%d timeWaitedMS:%d\n", timeoutMS, timeWaitedMS );
	if( timeWaitedMS >= timeoutMS )
	{
	    char* addrport = collabclient_makeAddressString( cc->address, cc->port );
	    gwwv_post_error(_("FontForge Collaboration"),
			    _("Failed to connect to server session at %s"),
			    addrport );
	    return 0;
	}

        kvmsg_t *kvmsg = kvmsg_recv_full( cc->snapshot, ZMQ_DONTWAIT );
	if (!kvmsg)
	{
	    int msToWait = 50;
	    g_usleep( msToWait * 1000 );
	    timeWaitedMS += msToWait;
	    continue;
        }
	
    
        /* kvmsg_t *kvmsg = kvmsg_recv (cc->snapshot); */
        /* if (!kvmsg) */
        /*     break;          //  Interrupted */
	
        if (streq (kvmsg_key (kvmsg), "KTHXBAI")) {
            cc->sequence = kvmsg_sequence (kvmsg);
            printf ("I: received snapshot=%d\n", (int) cc->sequence);
            kvmsg_destroy (&kvmsg);
	    // Done
            break;
        }
	printf ("I: storing seq=%ld ", kvmsg_sequence (kvmsg));
	if( kvmsg_get_prop (kvmsg, "type") )
	    printf(" type:%s", kvmsg_get_prop (kvmsg, "type") );
	printf ("\n");
	if( !strcmp(kvmsg_get_prop (kvmsg, "type"), MSG_TYPE_SFD ))
	{
	    if( !lastSFD ||
		kvmsg_sequence (kvmsg) > kvmsg_sequence (lastSFD))
	    {
		lastSFD = kvmsg;
	    }
	    size_t data_size = kvmsg_size(lastSFD);
	    printf("data_size:%ld\n", data_size );
	}
	kvmsg_store (&kvmsg, cc->kvmap);
    }
    printf("collabclient_sessionJoin(done with netio getting snapshot)\n");
    printf("collabclient_sessionJoin() lastSFD:%p\n", lastSFD );

//    int rc = 0;

//    void* out = 0;
//    rc = zhash_foreach ( cc->kvmap, collabclient_sessionJoin_findSFD_foreach_fn, &out );
    
//    printf("collabclient_sessionJoin() last sfd:%p\n", out );

    if( !lastSFD )
    {
	gwwv_post_error(_("FontForge Collaboration"), _("No Font Snapshot received from the server"));
	return 0;
    }
    
    if( lastSFD )
    {
	int openflags = 0;
	char filename[PATH_MAX];
	snprintf(filename, PATH_MAX, "%s/fontforge-collab-import-%d.sfd",getTempDir(),getpid());
	GFileWriteAll( filename, kvmsg_body (lastSFD) );

	/*
	 * Since we are creating a new fontview window for the collab session
	 * we "hand over" the collabClient from the current fontview used to join
	 * the session to the fontview which owns the sfd from the wire.
	 */ 
	FontViewBase* newfv = ViewPostScriptFont( filename, openflags );
	newfv->collabClient = cc;
	fv->b.collabClient = 0;
	newfv->collabState = cs_client;
	FVTitleUpdate( newfv );
	collabclient_notifySessionJoining( cc, newfv );

	ret = newfv;
	/* cloneclient_t* newc = collabclient_new( cc->address, cc->port ); */
	/* collabclient_sessionJoin( newc, fv ); */
    }

    
    printf("applying updates from server that were performed after the SFD snapshot was done...\n");
    
    kvmap_visit( cc->kvmap, kvmsg_sequence (lastSFD),
		 collabclient_sessionJoin_processmsg_foreach_fn, cc );

    /* struct collabclient_sessionJoin_processUpdates_foreach_args args; */
    /* args.cc = cc; */
    /* args.lastSFD = lastSFD; */
    /* rc = zhash_foreach ( cc->kvmap, collabclient_sessionJoin_processUpdates_foreach_fn, &args ); */
    
    

    printf("collabclient_sessionJoin(complete)\n");

#endif
    return ret;
}
コード例 #7
0
/**
 *  COllect Updates
 *  
 *  We store each update with a new sequence number, and if necessary, a
 *  time-to-live. We publish updates immediately on our publisher socket:
 */
static int
s_collector (zloop_t *loop, zmq_pollitem_t *poller, void *args)
{
    clonesrv_t *self = (clonesrv_t *) args;

    DEBUG("I: s_collector");
    
    kvmsg_t *kvmsg = kvmsg_recv (poller->socket);
    if (kvmsg) {
        kvmsg_set_sequence (kvmsg, ++self->sequence);
	kvmsg_fmt_key(kvmsg, "%s%d", SUBTREE, self->sequence-1 );

	if( !strcmp(MSG_TYPE_SFD, kvmsg_get_prop (kvmsg, "type")))
	{
	    // setup the beacon
	    //  Broadcast on the zyre port
	    beacon_announce_t ba;
	    memset( &ba, 0, sizeof(ba));
	    strcpy( ba.protocol, "fontforge-collab" );
	    ba.version = 2;
	    char* uuid = kvmsg_get_prop (kvmsg, "collab_uuid" );
	    if( uuid ) {
		strcpy( ba.uuid, uuid );
	    } else {
		ff_uuid_generate( ba.uuid );
	    }
	    strncpy( ba.username,    GetAuthor(), beacon_announce_username_sz );
	    ff_gethostname( ba.machinename, beacon_announce_machinename_sz );
	    ba.port = htons( self->port );
	    strcpy( ba.fontname, "" );

	    DEBUG("I: adding beacon, payloadsz:%zu user:%s machine:%s",
		  sizeof(beacon_announce_t), ba.username, ba.machinename );

	    
	    char* fontname = kvmsg_get_prop (kvmsg, "fontname" );
	    if( fontname )
	    {
		strcpy( ba.fontname, fontname );
	    }


	    service_beacon = zbeacon_new( self->ctx, 5670 );
	    zbeacon_set_interval (service_beacon, 300 );
	    zbeacon_publish (service_beacon, (byte*)&ba, sizeof(ba));
	}
	
	
        kvmsg_send (kvmsg, self->publisher);
//        int ttl = atoi (kvmsg_get_prop (kvmsg, "ttl"));
//        if (ttl)
//            kvmsg_set_prop (kvmsg, "ttl",
//                "%" PRId64, zclock_time () + ttl * 1000);
        DEBUG ("I: publishing update=%d type:%s", (int) self->sequence,kvmsg_get_prop (kvmsg, "type"));
	DEBUG("I:x hash size:%ld", zhash_size(self->kvmap));
	
        kvmsg_store( &kvmsg, self->kvmap );
	
    }
    return 0;
}