public Agreement Run(string offerProposalId) { // 0. Validate the subscription var offerProposal = this.ProposalRepository.GetOfferProposal(offerProposalId); DemandSubscription subscription = this.SubscriptionRepository.GetDemandSubscription(offerProposal.ReceivingSubscriptionId); if (subscription != null) { // 1. Locate offer to which this demand is a response to, and put the OfferProposal in its Subscription pipeline var demand = offerProposal.DemandId == null ? subscription.Demand : this.ProposalRepository.GetDemandProposal(offerProposal.DemandId)?.Demand; if (offerProposal == null) { throw new Exception($"OfferProposalId {offerProposalId} not found in Proposal repository..."); } if (demand == null) { throw new Exception($"Demand Id {offerProposal.DemandId} for Offer Proposal Id {offerProposalId} not found..."); } // 2. Persist the agreement var agreement = this.AgreementRepository.CreateAgreement(demand, offerProposal); return(agreement); } else { throw new Exception($"Demand Subscription for Offer ProposalId {offerProposalId} does not exist..."); } }
public DemandSubscription CreateDemandSubscription(Demand demand) { var newInternalId = GetNextSubscriptionInternalId(); var newId = "" + Guid.NewGuid(); var now = DateTime.Now; var result = new DemandSubscription() { Demand = demand, Id = newId, CreatedDate = now, LastActiveDate = now, LastReceivedProposalId = null }; //demand.Id = newId; lock (SubscriptionsLock) { this.Subscriptions.Add(newId, result); this.SubscriptionProposals.Add(newId, new List <Proposal>()); } return(result); }
public void DoSubscriptionCleanup(DemandSubscription demandSubscription, OfferSubscription offerSubscription) { this.RequestorProcessor.UnsubscribeDemand(demandSubscription.Id); this.ProviderProcessor.UnsubscribeOffer(offerSubscription.Id); }
public async Task <OfferProposal> DoSimpleOfferNegotiation(DemandSubscription demandSubscription, OfferSubscription offerSubscription, OfferProposal offerProposal) { // OK, we got an offer proposal, we can now send a direct Demand counterproposal var counterDemand = new Demand() { Constraints = @"(&" + @"(golem.srv.comp.container.docker.image=golemfactory/ffmpeg)" + @"(golem.srv.comp.container.docker.benchmark{golemfactory/ffmpeg}>300)" + @"(golem.com.payment.scheme=after)" + @"(golem.usage.vector=[golem.usage.duration_sec])" + @"(golem.com.pricing.model=linear)" + @"(golem.com.pricing.model.linear.coeffs=*)" + //@"(golem.com.pricing.est{[30]}<125)" + @")", NodeId = "RequestorA", // must be assigned from the outside Properties = new Dictionary <string, string>() }; var counterDemandProposal = RequestorProcessor.CreateDemandProposal(demandSubscription.Id, offerProposal.Id, counterDemand); // At this point, the Provider should be able to read the Demand Proposal on the Offer subscription var provEvents = await ProviderProcessor.CollectProviderEventsAsync(offerSubscription.Id, 1000, 10); Assert.IsTrue(provEvents.Any()); Assert.AreEqual(counterDemandProposal.Id, provEvents.First().DemandProposal.Id); Assert.AreEqual(offerProposal.Id, provEvents.First().DemandProposal.OfferId); // ...if we call again - there should be no proposals, so a timeout is expected after 100ms var provEvents2 = await ProviderProcessor.CollectProviderEventsAsync(offerSubscription.Id, 100, 10); Assert.IsFalse(provEvents2.Any()); // Now test the blocking logic of Collect - hang on Collect on Requestor side, while Provider sends counter-offer ICollection <MarketRequestorEvent> reqEvents2 = null; Task.Run(async() => { reqEvents2 = await RequestorProcessor.CollectRequestorEventsAsync(demandSubscription.Id, 5000, 10); Assert.IsTrue(reqEvents2.Any()); }); // ...and prepare counter-offer with price var counterOffer = new Offer() { Constraints = "()", NodeId = "ProviderB", Properties = new Dictionary <string, string>() { { "golem.srv.comp.container.docker.image", @"[""golemfactory/ffmpeg""]" }, { "golem.srv.comp.container.docker.benchmark{golemfactory/ffmpeg}", @"723" }, { "golem.srv.comp.container.docker.benchmark{*}", null }, { "golem.inf.cpu.cores", @"4" }, { "golem.inf.cpu.threads", @"8" }, { "golem.inf.mem.gib", @"16" }, { "golem.inf.storage.gib", @"30" }, { "golem.usage.vector", @"[""golem.usage.duration_sec""]" }, { "golem.com.payment.scheme", @"""after""" }, { "golem.com.pricing.model", @"""linear""" }, { "golem.com.pricing.model.linear.coeffs", @"[0, 0.2]" }, { "golem.com.pricing.est{*}", null }, } }; var counterOfferProposal = ProviderProcessor.CreateOfferProposal(offerSubscription.Id, provEvents.First().DemandProposal.Id, counterOffer); Thread.Sleep(1000); Assert.IsTrue(reqEvents2.Any()); Assert.AreEqual(counterDemandProposal.Id, reqEvents2.First().OfferProposal.DemandId); return(reqEvents2.First().OfferProposal); }