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...");
            }
        }
예제 #2
0
        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);
        }
예제 #3
0
 public void DoSubscriptionCleanup(DemandSubscription demandSubscription, OfferSubscription offerSubscription)
 {
     this.RequestorProcessor.UnsubscribeDemand(demandSubscription.Id);
     this.ProviderProcessor.UnsubscribeOffer(offerSubscription.Id);
 }
예제 #4
0
        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);
        }