示例#1
0
void SG_pull__clone(
	SG_context* pCtx, 
	const char* pszPullIntoRepoDescriptorName, 
	SG_client* pClient)
{
	sg_pull_instance_data* pMe = NULL;
	char* pszFragballName = NULL;
	const SG_pathname* pStagingPathname;

	SG_NULLARGCHECK_RETURN(pszPullIntoRepoDescriptorName);
	SG_NULLARGCHECK_RETURN(pClient);

	SG_ERR_CHECK(  _pull_init(pCtx, pClient, pszPullIntoRepoDescriptorName, &pMe)  );
	SG_ERR_CHECK(  SG_staging__get_pathname(pCtx, pMe->pStaging, &pStagingPathname)  );

	/* Request a fragball containing the entire repo */
	SG_ERR_CHECK(  SG_client__pull_clone(pCtx, pClient, pStagingPathname, &pszFragballName)  );

	/* commit and cleanup */
	SG_ERR_CHECK_RETURN(  SG_staging__commit_fragball(pCtx, pMe->pStaging, pszFragballName)  );

	SG_ERR_CHECK(  SG_context__msg__emit(pCtx, "Cleaning up...")  );
	SG_ERR_CHECK_RETURN(  SG_staging__cleanup(pCtx, &pMe->pStaging)  );
	SG_ERR_CHECK(  SG_context__msg__emit(pCtx, "done")  );

	/* fall through */
fail:
	_NULLFREE_INSTANCE_DATA(pCtx, pMe);
	SG_NULLFREE(pCtx, pszFragballName);
	SG_ERR_IGNORE(  SG_context__msg__emit(pCtx, "\n")  );
}
示例#2
0
void sg_client__c__pull_clone(
	SG_context* pCtx,
	SG_client* pClient,
	const SG_pathname* pStagingPathname,
	char** ppszFragballName)
{
	sg_client_c_instance_data* pMe = NULL;
	SG_repo* pRepo = NULL;
	SG_vhash* pvhStatus = NULL;

	SG_NULLARGCHECK_RETURN(pClient);
	SG_NULLARGCHECK_RETURN(ppszFragballName);

	pMe = (sg_client_c_instance_data*)pClient->p_vtable_instance_data;

	SG_ERR_CHECK(  SG_repo__open_repo_instance(pCtx, pClient->psz_remote_repo_spec, &pRepo)  );

	SG_ERR_CHECK(  SG_context__msg__emit(pCtx, "Copying repository...")  );
	SG_ERR_CHECK(  SG_repo__fetch_repo__fragball(pCtx, pRepo, pStagingPathname, ppszFragballName) );
	SG_ERR_CHECK(  SG_context__msg__emit(pCtx, "done")  );

	/* fall through */
fail:
	SG_REPO_NULLFREE(pCtx, pRepo);
	SG_VHASH_NULLFREE(pCtx, pvhStatus);
	SG_ERR_IGNORE(  SG_context__msg__emit(pCtx, "\n")  );
}
示例#3
0
static void _add_dagnodes_until_connected(SG_context* pCtx, 
										  SG_vhash** ppvhStagingStatus, 
										  sg_pull_instance_data* pMe, 
										  SG_client* pClient)
{
	SG_bool disconnected = SG_FALSE;
	SG_vhash* pvhFragballRequest = NULL;
	char* pszFragballName = NULL;
	SG_vhash* pvhRequestStatus = NULL;
	const SG_pathname* pStagingPathname;

	SG_ERR_CHECK(  SG_staging__get_pathname(pCtx, pMe->pStaging, &pStagingPathname)  );

	SG_ERR_CHECK(  SG_vhash__has(pCtx, *ppvhStagingStatus, SG_SYNC_STATUS_KEY__DAGS, &disconnected)  );
	while (disconnected)
	{

#if TRACE_PULL
		SG_ERR_CHECK(  SG_vhash_debug__dump_to_console__named(pCtx, *ppvhStagingStatus, "pull staging status")  );
#endif
		// There's at least one dag with connection problems.  
		
		// Convert the staging status vhash into a fragball request vhash.
		pvhFragballRequest = *ppvhStagingStatus;
		*ppvhStagingStatus = NULL;
		SG_ERR_CHECK(  SG_vhash__add__int64(pCtx, pvhFragballRequest, SG_SYNC_STATUS_KEY__GENERATIONS, GENERATIONS_PER_ROUNDTRIP)  );

		SG_ERR_CHECK(  SG_client__pull_request_fragball(pCtx, pClient, pvhFragballRequest, pStagingPathname, &pszFragballName, &pvhRequestStatus)  );

		/* Ian TODO: inspect pvhRequestStatus */

		SG_VHASH_NULLFREE(pCtx, pvhRequestStatus);
		SG_VHASH_NULLFREE(pCtx, pvhFragballRequest);

		SG_ERR_CHECK(  SG_staging__slurp_fragball(pCtx, pMe->pStaging, (const char*)pszFragballName)  );
		SG_NULLFREE(pCtx, pszFragballName);

		SG_ERR_CHECK(  SG_staging__check_status(pCtx, pMe->pStaging, SG_TRUE, SG_FALSE, SG_FALSE, SG_FALSE, SG_FALSE, ppvhStagingStatus)  );

		SG_ERR_CHECK(  SG_vhash__has(pCtx, *ppvhStagingStatus, SG_SYNC_STATUS_KEY__DAGS, &disconnected)  );

#if TRACE_PULL
		SG_ERR_CHECK(  SG_vhash_debug__dump_to_console__named(pCtx, *ppvhStagingStatus, "pull staging status")  );
#endif
	}

	SG_ERR_CHECK_RETURN(  SG_context__msg__emit(pCtx, "done")  );

	/* fall through */
fail:
	SG_VHASH_NULLFREE(pCtx, *ppvhStagingStatus);
	SG_VHASH_NULLFREE(pCtx, pvhFragballRequest);
	SG_NULLFREE(pCtx, pszFragballName);
	SG_VHASH_NULLFREE(pCtx, pvhRequestStatus);
	SG_ERR_IGNORE(  SG_context__msg__emit(pCtx, "\n")  );
}
示例#4
0
static void _add_blobs_until_done(SG_context* pCtx, 
								  SG_staging* pStaging, 
								  SG_client* pClient) 
{
	SG_bool need_blobs = SG_FALSE;
	SG_vhash* pvhFragballRequest = NULL;
	char* pszFragballName = NULL;
	SG_vhash* pvhRequestStatus = NULL;
	const SG_pathname* pStagingPathname = NULL;
	SG_vhash* pvhStagingStatus = NULL;

	SG_ERR_CHECK_RETURN(  SG_context__msg__emit(pCtx, "Retrieving blobs...")  );

	SG_ERR_CHECK(  SG_staging__check_status(pCtx, pStaging, SG_FALSE, SG_FALSE, SG_FALSE, SG_TRUE, SG_TRUE, &pvhStagingStatus)  );

	SG_ERR_CHECK(  SG_vhash__has(pCtx, pvhStagingStatus, SG_SYNC_STATUS_KEY__BLOBS, &need_blobs)  );
	
	if (need_blobs)
		SG_ERR_CHECK(  SG_staging__get_pathname(pCtx, pStaging, &pStagingPathname)  );

	while (need_blobs)
	{
		pvhFragballRequest = pvhStagingStatus;
		pvhStagingStatus = NULL;

		SG_ERR_CHECK(  SG_client__pull_request_fragball(pCtx, pClient, pvhFragballRequest, pStagingPathname, &pszFragballName, &pvhRequestStatus)  );

		/* Ian TODO: inspect pvhRequestStatus */

		SG_VHASH_NULLFREE(pCtx, pvhRequestStatus);
		SG_VHASH_NULLFREE(pCtx, pvhFragballRequest);

		SG_ERR_CHECK(  SG_staging__slurp_fragball(pCtx, pStaging, (const char*)pszFragballName)  );
		SG_NULLFREE(pCtx, pszFragballName);

		SG_ERR_CHECK(  SG_staging__check_status(pCtx, pStaging, SG_FALSE, SG_FALSE, SG_FALSE, SG_TRUE, SG_TRUE, &pvhStagingStatus)  );

#if TRACE_PULL
		SG_ERR_CHECK(  SG_vhash_debug__dump_to_console__named(pCtx, pvhStagingStatus, "pull staging status")  );
#endif

		SG_ERR_CHECK(  SG_vhash__has(pCtx, pvhStagingStatus, SG_SYNC_STATUS_KEY__BLOBS, &need_blobs)  );
	}

	SG_ERR_CHECK_RETURN(  SG_context__msg__emit(pCtx, "done")  );

	/* fall through */
fail:
	SG_VHASH_NULLFREE(pCtx, pvhStagingStatus);
	SG_VHASH_NULLFREE(pCtx, pvhFragballRequest);
	SG_NULLFREE(pCtx, pszFragballName);
	SG_VHASH_NULLFREE(pCtx, pvhRequestStatus);
	SG_ERR_IGNORE(  SG_context__msg__emit(pCtx, "\n")  );
}
示例#5
0
void SG_pull__all__list_incoming(
	SG_context* pCtx,
	const char* pszPullIntoRepoDescriptorName,
	SG_client* pClient,
	SG_varray** ppvaInfo)
{
	sg_pull_instance_data* pMe = NULL;
	char* pszFragballName = NULL;
	SG_vhash* pvhStatus = NULL; // Used for both fragball request status returned by SG_client
	// and staging status returned by SG_staging.
	const SG_pathname* pStagingPathname;

	SG_NULLARGCHECK_RETURN(pszPullIntoRepoDescriptorName);
	SG_NULLARGCHECK_RETURN(pClient);

	SG_ERR_CHECK(  _pull_init(pCtx, pClient, pszPullIntoRepoDescriptorName, &pMe)  );
	SG_ERR_CHECK(  SG_staging__get_pathname(pCtx, pMe->pStaging, &pStagingPathname)  );

	/* Request a fragball containing leaves of every dag */
	SG_ERR_CHECK_RETURN(  SG_context__msg__emit(pCtx, "Retrieving dagnodes...")  );
	SG_ERR_CHECK(  SG_client__pull_request_fragball(pCtx, pClient, NULL, pStagingPathname, &pszFragballName, &pvhStatus)  );

	/* Ian TODO: inspect pvhStatus */

	SG_ERR_CHECK(  SG_VHASH_NULLFREE(pCtx, pvhStatus)  );

	SG_ERR_CHECK(  SG_staging__slurp_fragball(pCtx, pMe->pStaging, pszFragballName)  );
	SG_ERR_CHECK(  SG_staging__check_status(pCtx, pMe->pStaging, SG_TRUE, SG_FALSE, SG_FALSE, SG_FALSE, SG_FALSE, &pvhStatus)  );

	/* Check the status and use it to request more dagnodes until the dags connect */
	SG_ERR_CHECK(  _add_dagnodes_until_connected(pCtx, &pvhStatus, pMe, pClient)  );
	SG_ERR_CHECK(  SG_VHASH_NULLFREE(pCtx, pvhStatus)  );

	SG_ERR_CHECK(  SG_staging__check_status(pCtx, pMe->pStaging, SG_FALSE, SG_FALSE, SG_TRUE, SG_FALSE, SG_FALSE, &pvhStatus)  );
	{
		SG_bool b = SG_FALSE;
		SG_vhash* pvhRequest = NULL;
		SG_ERR_CHECK(  SG_vhash__has(pCtx, pvhStatus, SG_SYNC_STATUS_KEY__NEW_NODES, &b)  );
		if (b)
		{
			/* There are incoming nodes.  Get their info. */
			SG_ERR_CHECK(  SG_vhash__get__vhash(pCtx, pvhStatus, SG_SYNC_STATUS_KEY__NEW_NODES, &pvhRequest)  );
			SG_ERR_CHECK(  SG_client__get_dagnode_info(pCtx, pClient, pvhRequest, ppvaInfo)  );
		}
	}

	/* fall through */
fail:
	_NULLFREE_INSTANCE_DATA(pCtx, pMe);
	SG_VHASH_NULLFREE(pCtx, pvhStatus);
	SG_NULLFREE(pCtx, pszFragballName);
}
示例#6
0
/**
 * To be called after an initial roundtrip in which the initial leaves for the pull were added.
 * Caller should provide the (address of the) status vhash from that initial server roundtrip, we'll free it.
 * This routine will complete the pull.
 */
static void _pull_common(SG_context* pCtx,
						 SG_client* pClient,
						 SG_vhash** ppvhStagingStatus,
						 sg_pull_instance_data* pMe,
						 SG_varray** ppvaErr,
						 SG_varray** ppvaLog)
{
	/* Check the status and use it to request more dagnodes until the dags connect */
	SG_ERR_CHECK_RETURN(  _add_dagnodes_until_connected(pCtx, ppvhStagingStatus, pMe, pClient)  );

	/* All necessary dagnodes are in the frag at this point.  Now get remaining missing blobs. */
	SG_ERR_CHECK_RETURN(  _add_blobs_until_done(pCtx, pMe->pStaging, pClient)  );

	/* commit and cleanup */
	SG_ERR_CHECK_RETURN(  SG_context__msg__emit(pCtx, "Committing changes...")  );
	SG_ERR_CHECK_RETURN(  SG_staging__commit(pCtx, pMe->pStaging)  );
	SG_ERR_CHECK_RETURN(  SG_context__msg__emit(pCtx, "done\n")  );
	SG_ERR_CHECK_RETURN(  SG_staging__cleanup(pCtx, &pMe->pStaging)  );

	/* auto-merge zing dags */
	SG_ERR_CHECK_RETURN(  SG_zing__auto_merge_all_dags(pCtx, pMe->pPullIntoRepo, ppvaErr, ppvaLog)  );
}
示例#7
0
void SG_pull__commit(
	SG_context* pCtx,
	SG_pull** ppPull,
	SG_varray** ppvaZingErr,
	SG_varray** ppvaZingLog)
{
	_sg_pull* pMyPull = NULL;
	sg_pull_instance_data* pMe = NULL;
	SG_vhash* pvhStatus = NULL;
	char* pszFragballName = NULL;
	const SG_pathname* pStagingPathname;
	
	SG_NULL_PP_CHECK_RETURN(ppPull);
	pMyPull = (_sg_pull*)*ppPull;
	pMe = pMyPull->pPullInstance;

	SG_ERR_CHECK(  SG_staging__get_pathname(pCtx, pMe->pStaging, &pStagingPathname)  );

	SG_ERR_CHECK_RETURN(  SG_context__msg__emit(pCtx, "Retrieving dagnodes...")  );
	SG_ERR_CHECK(  SG_client__pull_request_fragball(pCtx, pMyPull->pClient, pMyPull->pvhFragballRequest, pStagingPathname, &pszFragballName, &pvhStatus)  );
#if TRACE_PULL
	SG_ERR_CHECK(  SG_vhash_debug__dump_to_console__named(pCtx, pvhStatus, "pull staging status")  );
#endif

	/* Ian TODO: check status of pull request */

	SG_ERR_CHECK(  SG_VHASH_NULLFREE(pCtx, pvhStatus)  );

	SG_ERR_CHECK(  SG_staging__slurp_fragball(pCtx, pMe->pStaging, pszFragballName)  );
	SG_ERR_CHECK(  SG_staging__check_status(pCtx, pMe->pStaging, SG_TRUE, SG_FALSE, SG_FALSE, SG_FALSE, SG_FALSE, &pvhStatus)  );

	/* Finish the pull using the status data we got back. */
	SG_ERR_CHECK(  _pull_common(pCtx, pMyPull->pClient, &pvhStatus, pMe, ppvaZingErr, ppvaZingLog)  );

	/* fall through */
fail:
	SG_ERR_IGNORE(  _sg_pull__nullfree(pCtx, (_sg_pull**)ppPull)  );
	SG_VHASH_NULLFREE(pCtx, pvhStatus);
	SG_NULLFREE(pCtx, pszFragballName);
}
示例#8
0
void SG_pull__all(SG_context* pCtx, 
				  const char* pszPullIntoRepoDescriptorName, 
				  SG_client* pClient,
				  SG_varray** ppvaErr,
				  SG_varray** ppvaLog)
{
	sg_pull_instance_data* pMe = NULL;
	char* pszFragballName = NULL;
	SG_vhash* pvhStatus = NULL; // Used for both fragball request status returned by SG_client
								// and staging status returned by SG_staging.
	const SG_pathname* pStagingPathname;

	SG_NULLARGCHECK_RETURN(pszPullIntoRepoDescriptorName);
	SG_NULLARGCHECK_RETURN(pClient);

	SG_ERR_CHECK(  _pull_init(pCtx, pClient, pszPullIntoRepoDescriptorName, &pMe)  );
	SG_ERR_CHECK(  SG_staging__get_pathname(pCtx, pMe->pStaging, &pStagingPathname)  );

	/* Request a fragball containing leaves of every dag */
	SG_ERR_CHECK_RETURN(  SG_context__msg__emit(pCtx, "Retrieving dagnodes...")  );
	SG_ERR_CHECK(  SG_client__pull_request_fragball(pCtx, pClient, NULL, pStagingPathname, &pszFragballName, &pvhStatus)  );

	/* Ian TODO: inspect pvhStatus */

	SG_ERR_CHECK(  SG_VHASH_NULLFREE(pCtx, pvhStatus)  );

	SG_ERR_CHECK(  SG_staging__slurp_fragball(pCtx, pMe->pStaging, pszFragballName)  );
	SG_ERR_CHECK(  SG_staging__check_status(pCtx, pMe->pStaging, SG_TRUE, SG_FALSE, SG_FALSE, SG_FALSE, SG_FALSE, &pvhStatus)  );

	/* Finish the pull using the status data we got back. */
	SG_ERR_CHECK(  _pull_common(pCtx, pClient, &pvhStatus, pMe, ppvaErr, ppvaLog)  );

	/* fall through */
fail:
	_NULLFREE_INSTANCE_DATA(pCtx, pMe);
	SG_VHASH_NULLFREE(pCtx, pvhStatus);
	SG_NULLFREE(pCtx, pszFragballName);
}